]> andersk Git - splint.git/blame - src/uentry.c
Updated copyright date.
[splint.git] / src / uentry.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
77d37419 3** Copyright (C) 1994-2002 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
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
146e25eb 46static void uentry_showWhereLastKind (uentry p_spec) /*@modifies g_msgstream@*/ ;
f2b6724f 47
28bf4b0b 48static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
49 /*@modifies p_ue@*/ ;
50
51static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
52 /*@modifies p_ue@*/ ;
53
616915dd 54/*@access ekind@*/
55static void checkAliasState (/*@notnull@*/ uentry p_old,
56 /*@notnull@*/ uentry p_unew,
57 bool p_mustConform, bool p_completeConform)
58 /*@modifies p_old, p_unew@*/ ;
59static void checkNullState (/*@notnull@*/ uentry p_old,
60 /*@notnull@*/ uentry p_unew,
61 bool p_mustConform, bool p_completeConform)
62 /*@modifies p_old, p_unew@*/ ;
63
64static void checkVarConformance (/*@notnull@*/ uentry p_old,
65 /*@notnull@*/ uentry p_unew,
66 bool p_mustConform, bool p_completeConform)
67 /*@modifies p_old, p_unew@*/;
68
69# ifndef NOLCL
70static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
71static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
72# endif
73
74static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
75
76static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
77 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
78 /*@modifies p_e@*/;
79
80static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
81static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
82static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
83static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
84static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
85static void
86 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
87 ctype p_oldType, /*@notnull@*/ uentry p_unew,
88 /*@notnull@*/ uentry p_newCurrent,
89 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
90
91static /*@only@*/ /*@notnull@*/ uentry
92 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
93 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
94
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 {
77d37419 1616 /* drl 11-29-2002
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
ac35a6ab 3363 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3364 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
616915dd 3365
3366 /*
ac35a6ab 3367 ** expanded macro is marked used
616915dd 3368 */
3369
efd360a3 3370 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
616915dd 3371
3372 ue->ukind = KFCN;
3373 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3374 ue->info->fcn->exitCode = XK_UNKNOWN;
28bf4b0b 3375 ue->info->fcn->nullPred = qual_createUnknown ();
616915dd 3376 ue->info->fcn->specialCode = SPC_NONE;
3377 ue->info->fcn->access = typeIdSet_undefined;
3378 ue->info->fcn->hasGlobs = FALSE;
3379 ue->info->fcn->globs = globSet_undefined;
3380 ue->info->fcn->hasMods = FALSE;
3381 ue->info->fcn->mods = sRefSet_undefined;
3382 ue->info->fcn->specclauses = NULL;
3383 ue->info->fcn->defparams = uentryList_undefined;
3384
3385 /*drl*/
3814599d 3386 ue->info->fcn->preconditions = functionConstraint_undefined;
616915dd 3387 /*end */
3388
3389 /*drl 12/28/2000*/
efd360a3 3390 ue->info->fcn->postconditions = functionConstraint_undefined;
616915dd 3391 /*end */
616915dd 3392
3393 if (ctype_isFunction (ue->utype))
3394 {
28bf4b0b 3395 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
616915dd 3396 }
3397 else
3398 {
3399 ue->sref = sRef_makeType (ctype_unknown);
3400 }
3401
3402 if (sRef_isRefCounted (ue->sref))
3403 {
3404 ak = AK_NEWREF;
3405 }
3406 else
3407 {
3408 if (alkind_isUnknown (ak))
3409 {
3410 if (exkind_isKnown (ek))
3411 {
28bf4b0b 3412 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
616915dd 3413 ak = AK_IMPDEPENDENT;
3414 }
3415 else
3416 {
3417 if (context_getFlag (FLG_RETIMPONLY))
3418 {
3419 if (ctype_isFunction (ue->utype)
3420 && ctype_isVisiblySharable
28bf4b0b 3421 (ctype_realType (ctype_getReturnType (ue->utype))))
616915dd 3422 {
3423 if (uentryList_hasReturned (uentry_getParams (ue)))
3424 {
3425 ;
3426 }
3427 else
3428 {
28bf4b0b 3429 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3430 {
3431 ;
3432 }
3433 else
3434 {
3435 ak = AK_IMPONLY;
3436 }
3437 }
616915dd 3438 }
3439 }
3440 }
3441 }
3442 }
3443
3444 loc = ue->whereDeclared;
3445
3446 sRef_setAliasKind (ue->sref, ak, loc);
3447 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3448 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3449 sRef_setExKind (ue->sref, ek, loc);
3450
3451 if (oldInfo->kind == VKEXPMACRO)
3452 {
efd360a3 3453 ;
616915dd 3454 }
3455 else
3456 {
3457 fileloc_free (ue->whereDefined);
3458 ue->whereDefined = fileloc_undefined;
3459 }
3460
3461 uvinfo_free (oldInfo);
3462}
3463
b072092f 3464void uentry_makeConstantFunction (uentry ue)
3465{
3466 alkind ak;
3467 exkind ek;
3468 ucinfo oldInfo;
3469 fileloc loc;
3470
3471 llassert (uentry_isValid (ue));
3472 llassert (!sRef_modInFunction ());
3473
3474 ak = sRef_getOrigAliasKind (ue->sref);
3475 ek = sRef_getOrigExKind (ue->sref);
3476
3477 llassert (uentry_isConstant (ue));
3478 oldInfo = ue->info->uconst;
3479
3480 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3481
3482 /*
3483 ** expanded macro is marked used (until I write a pre-processor)
3484 */
3485
3486 ue->ukind = KFCN;
3487 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3488 ue->info->fcn->exitCode = XK_UNKNOWN;
3489 ue->info->fcn->nullPred = qual_createUnknown ();
3490 ue->info->fcn->specialCode = SPC_NONE;
3491 ue->info->fcn->access = typeIdSet_undefined;
3492 ue->info->fcn->hasGlobs = FALSE;
3493 ue->info->fcn->globs = globSet_undefined;
3494 ue->info->fcn->hasMods = FALSE;
3495 ue->info->fcn->mods = sRefSet_undefined;
3496 ue->info->fcn->specclauses = NULL;
3497 ue->info->fcn->defparams = uentryList_undefined;
3498
3499 /*drl*/
3500 ue->info->fcn->preconditions = functionConstraint_undefined;
3501 /*end */
3502
3503 /*drl 12/28/2000*/
3504 ue->info->fcn->postconditions = functionConstraint_undefined;
3505 /*end */
3506
3507
3508 if (ctype_isFunction (ue->utype))
3509 {
3510 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3511 }
3512 else
3513 {
3514 ue->sref = sRef_makeType (ctype_unknown);
3515 }
3516
3517 if (sRef_isRefCounted (ue->sref))
3518 {
3519 ak = AK_NEWREF;
3520 }
3521 else
3522 {
3523 if (alkind_isUnknown (ak))
3524 {
3525 if (exkind_isKnown (ek))
3526 {
3527 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3528 ak = AK_IMPDEPENDENT;
3529 }
3530 else
3531 {
3532 if (context_getFlag (FLG_RETIMPONLY))
3533 {
3534 if (ctype_isFunction (ue->utype)
3535 && ctype_isVisiblySharable
3536 (ctype_realType (ctype_getReturnType (ue->utype))))
3537 {
3538 if (uentryList_hasReturned (uentry_getParams (ue)))
3539 {
3540 ;
3541 }
3542 else
3543 {
3544 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3545 {
3546 ;
3547 }
3548 else
3549 {
3550 ak = AK_IMPONLY;
3551 }
3552 }
3553 }
3554 }
3555 }
3556 }
3557 }
3558
3559 loc = ue->whereDeclared;
3560
3561 sRef_setAliasKind (ue->sref, ak, loc);
3562 sRef_setExKind (ue->sref, ek, loc);
3563
3564 fileloc_free (ue->whereDefined);
3565 ue->whereDefined = fileloc_undefined;
3566 ucinfo_free (oldInfo);
3567}
3568
616915dd 3569void
3570uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3571{
3572 llassert (uentry_isValid (ue));
3573
3574 if (uentry_isIter (ue))
3575 {
3576 llassert (globSet_isUndefined (ue->info->iter->globs));
3577 ue->info->iter->globs = globs;
3578 }
3579 else
3580 {
efd360a3 3581 uentry_convertVarFunction (ue);
616915dd 3582
3583 llassert (uentry_isFunction (ue));
3584 llassert (!ue->info->fcn->hasGlobs
3585 && globSet_isUndefined (ue->info->fcn->globs));
3586
3587 ue->info->fcn->hasGlobs = TRUE;
28bf4b0b 3588 globSet_markImmutable (globs);
616915dd 3589 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3590 /*@=mustfree@*/
3591 }
3592
68de3f33 3593 /*@i23*/
3594 /* ??? - evans 2001-09-09 not sure what's going on here...?
616915dd 3595 if (globSet_hasStatic (globs))
3596 {
3597 context_recordFileGlobals (globs);
3598 }
28bf4b0b 3599 */
616915dd 3600
3601 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3602 {
3603 ue->info->fcn->hasMods = TRUE;
3604 }
3605}
3606
3607void uentry_addAccessType (uentry ue, typeId tid)
3608{
3609 if (uentry_isFunction (ue))
3610 {
3611 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3612 }
3613 else if (uentry_isEitherConstant (ue))
3614 {
3615 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3616 }
3617 else if (uentry_isIter (ue))
3618 {
3619 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3620 }
3621 else if (uentry_isEndIter (ue))
3622 {
3623 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3624 }
3625 else
3626 {
3627 llbug (message ("no access for: %q", uentry_unparse (ue)));
3628 }
3629}
3630
3631/*@only@*/ /*@notnull@*/ uentry
3632 uentry_makeFunction (cstring n, ctype t,
3633 typeId access,
3634 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
28bf4b0b 3635 /*@only@*/ warnClause warn,
616915dd 3636 fileloc f)
3637{
28bf4b0b 3638 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
616915dd 3639 return (uentry_makeFunctionAux (n, t,
3640 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3641 : typeIdSet_single (access)),
28bf4b0b 3642 globs, mods, warn,
3643 f,
616915dd 3644 FALSE, FALSE));
3645}
3646
3647# ifndef NOLCL
3648/*@notnull@*/ uentry
3649 uentry_makePrivFunction2 (cstring n, ctype t,
3650 typeIdSet access,
3651 globSet globs, sRefSet mods,
3652 fileloc f)
3653{
28bf4b0b 3654 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3655 f, TRUE, FALSE));
616915dd 3656}
3657
3658
3659/*@notnull@*/ uentry
3660 uentry_makeSpecFunction (cstring n, ctype t,
3661 typeIdSet access,
3662 /*@only@*/ globSet globs,
3663 /*@only@*/ sRefSet mods,
3664 fileloc f)
3665{
3666 uentry ue = uentry_makeFunctionAux (n, t, access,
28bf4b0b 3667 globs, mods, warnClause_undefined,
3668 f, FALSE, FALSE);
616915dd 3669
3670 uentry_setHasGlobs (ue);
3671 uentry_setHasMods (ue);
3672
3673 reflectImplicitFunctionQualifiers (ue, TRUE);
3674 return (ue);
3675}
3676# endif
3677
3678uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3679{
3680 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3681 sRef_undefined, FALSE, VKEXPMACRO);
3682
3683 uentry_setDefined (ue, f);
3684 return ue;
3685}
3686
3687/*@notnull@*/ /*@notnull@*/ uentry
3688 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3689{
3690 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3691 typeIdSet_singleOpt (access),
3692 globSet_undefined, sRefSet_undefined,
28bf4b0b 3693 warnClause_undefined,
616915dd 3694 fileloc_undefined,
3695 FALSE, TRUE);
3696
3697 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3698 return ue;
3699}
3700
3701bool uentry_isForward (uentry e)
3702{
3703 if (uentry_isValid (e))
3704 {
3705 ctype ct = uentry_getType (e);
3706
3707 return (ctype_isUnknown (ct)
3708 || (ctype_isFunction (ct)
28bf4b0b 3709 && ctype_isUnknown (ctype_getReturnType (ct))));
616915dd 3710 }
3711
3712 return FALSE;
3713}
3714
3715# ifndef NOLCL
3716/*@notnull@*/ uentry
3717uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3718{
3719 return (uentry_makeFunctionAux (n, ctype_unknown, access,
28bf4b0b 3720 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3721 f,FALSE, TRUE));
616915dd 3722}
3723
3724/*@notnull@*/ uentry
3725uentry_makeUnspecFunction (cstring n, ctype t,
3726 typeIdSet access,
3727 fileloc f)
3728{
28bf4b0b 3729 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3730 sRefSet_undefined, warnClause_undefined,
3731 f, FALSE, TRUE);
616915dd 3732
3733 reflectImplicitFunctionQualifiers (ue, TRUE);
3734 return ue;
3735}
3736# endif
3737
3738/*
3739** datatypes
3740*/
3741
3742/* is exported for use by usymtab_interface */
3743
3744/*@notnull@*/ uentry
28bf4b0b 3745 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
616915dd 3746 fileloc f, bool priv)
3747{
3748 uentry e = uentry_alloc ();
3749
3750 DPRINTF (("Make datatype: %s / %s",
3751 n, ctype_unparse (t)));
3752
3753 /* e->shallowCopy = FALSE; */
3754 e->ukind = KDATATYPE;
3755 e->uname = cstring_copy (n);
3756 e->utype = t;
3757 e->storageclass = SCNONE;
3758 e->sref = sRef_makeUnknown ();
3759
3760 if (ctype_isUA (t))
3761 {
3762 sRef_setStateFromType (e->sref, t);
3763 }
3764
3765 uentry_setSpecDef (e, f);
3766
28bf4b0b 3767 e->warn = warnClause_undefined; /*@i634@*/
616915dd 3768 e->uses = filelocList_new ();
3769 e->isPrivate = priv;
3770 e->hasNameError = FALSE;
3771
3772 e->used = FALSE;
3773 e->lset = FALSE;
3774
3775 e->info = (uinfo) dmalloc (sizeof (*e->info));
3776 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
28bf4b0b 3777 e->info->datatype->abs = abstract;
616915dd 3778 e->info->datatype->mut = mut;
3779 e->info->datatype->type = ctype_undefined;
3780
3781 if (uentry_isDeclared (e))
3782 {
3783 uentry_setDefined (e, f);
3784 }
3785
28bf4b0b 3786 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
616915dd 3787 {
3788 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3789 }
3790
3791 return (e);
3792}
3793
3794/*@notnull@*/ uentry
28bf4b0b 3795 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
616915dd 3796{
28bf4b0b 3797 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
616915dd 3798}
3799
28bf4b0b 3800/*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
616915dd 3801{
3802 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
28bf4b0b 3803 ctype_bool, NO, abstract,
616915dd 3804 fileloc_getBuiltin (),
3805 FALSE);
3806
3807 ret->info->datatype->type = ctype_bool;
3808 return ret;
3809}
3810
3811/*
3812** iters
3813*/
3814
3815static /*@only@*/ /*@notnull@*/ uentry
3816 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3817 /*@only@*/ fileloc f)
3818{
3819 uentry e = uentry_alloc ();
3820
3821 e->ukind = KITER;
3822 e->uname = cstring_copy (n);
3823 e->utype = ct;
3824 e->sref = sRef_makeUnknown ();
3825 e->storageclass = SCNONE;
3826 e->used = FALSE;
3827 e->lset = FALSE;
3828
3829 uentry_setSpecDef (e, f);
3830
28bf4b0b 3831 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3832 e->uses = filelocList_new ();
3833 e->isPrivate = FALSE;
3834 e->hasNameError = FALSE;
3835
3836 e->info = (uinfo) dmalloc (sizeof (*e->info));
3837 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3838 e->info->iter->access = access;
3839 e->info->iter->mods = sRefSet_undefined;
3840 e->info->iter->globs = globSet_undefined;
3841
3842 uentry_checkIterArgs (e);
3843 return (e);
3844}
3845
3846/*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3847{
3848 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3849}
3850
3851static /*@notnull@*/ uentry
3852uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3853{
3854 uentry e = uentry_alloc ();
3855
3856 /* e->shallowCopy = FALSE; */
3857 e->ukind = KENDITER;
3858 e->storageclass = SCNONE;
3859 e->uname = message ("end_%s", n);
3860 e->utype = ctype_unknown;
3861 e->sref = sRef_makeUnknown ();
3862
3863 uentry_setSpecDef (e, f);
3864
3865 e->used = FALSE;
3866 e->lset = FALSE;
3867
3868 e->uses = filelocList_new ();
3869 e->isPrivate = FALSE;
3870 e->hasNameError = FALSE;
3871
3872 e->info = (uinfo) dmalloc (sizeof (*e->info));
3873 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3874
3875 e->info->enditer->access = access;
3876
28bf4b0b 3877 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3878 return (e);
3879}
3880
3881/*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3882{
3883 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3884}
3885
3886/*
3887** tags
3888*/
3889
3890static /*@only@*/ /*@notnull@*/ uentry
3891 uentry_makeTagAux (cstring n, ctype t,
3892 /*@only@*/ fileloc fl,
3893 bool priv, ekind kind)
3894{
3895 uentry e = uentry_alloc ();
3896
3897 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3898 {
3899 llbuglit ("uentry_makeTagAux: not a tag type");
3900 }
3901
3902 e->ukind = kind;
3903 /* e->shallowCopy = FALSE; */
3904 e->uname = cstring_copy (n);
3905
3906 e->utype = t;
3907 e->sref = sRef_makeUnknown ();
3908 e->storageclass = SCNONE;
3909
3910 uentry_setSpecDef (e, fl);
3911
3912 e->used = FALSE;
3913 e->lset = FALSE;
3914
3915 e->uses = filelocList_new ();
3916 e->isPrivate = priv;
3917 e->hasNameError = FALSE;
3918
3919 e->info = (uinfo) dmalloc (sizeof (*e->info));
3920 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3921 e->info->datatype->abs = NO;
3922 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3923 e->info->datatype->type = t;
28bf4b0b 3924 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3925
3926 if (uentry_isDeclared (e))
3927 {
3928 uentry_setDefined (e, fl);
3929 }
3930
3931 return (e);
3932}
3933
3934uentry uentry_makeStructTagLoc (cstring n, ctype t)
3935{
3936 cstring sname = makeStruct (n);
3937 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3938
3939 cstring_free (sname);
3940 return (ret);
3941}
3942
3943/*@only@*/ uentry
3944uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3945{
3946 cstring sname = makeStruct (n);
3947 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3948
3949 cstring_free (sname);
3950 return ret;
3951}
3952
3953/*@only@*/ uentry
3954uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3955{
3956 cstring uname = makeUnion (n);
3957 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3958
3959 cstring_free (uname);
3960 return (ret);
3961}
3962
3963# ifndef NOLCL
3964uentry
3965uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3966{
3967 cstring ename = makeEnum (n);
3968 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3969
3970 cstring_free (ename);
3971 return ret;
3972}
3973# endif
3974
3975uentry
3976uentry_makeUnionTagLoc (cstring n, ctype t)
3977{
3978 cstring uname = makeUnion (n);
3979 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3980
3981 cstring_free (uname);
3982 return ret;
3983}
3984
3985uentry
3986uentry_makeEnumTagLoc (cstring n, ctype t)
3987{
3988 cstring ename = makeEnum (n);
3989 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3990
3991 cstring_free (ename);
3992 return ret;
3993}
3994
3995bool
3996uentry_isStructTag (uentry ue)
3997{
3998 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3999}
4000
4001bool
4002uentry_isUnionTag (uentry ue)
4003{
4004 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4005}
4006
4007bool
4008uentry_isEnumTag (uentry ue)
4009{
4010 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4011}
4012
4013bool
4014uentry_isAnyTag (uentry ue)
4015{
4016 return (uentry_isStructTag (ue)
4017 || uentry_isUnionTag (ue)
4018 || uentry_isEnumTag (ue));
4019}
4020
4021static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4022
4023extern void uentry_destroyMod (void)
4024 /*@globals killed emarker@*/ /*@modifies emarker@*/
4025{
4026 static bool wasDestroyed = FALSE;
4027
4028 llassert (!wasDestroyed);
4029
4030 if (emarker != NULL)
4031 {
4032 uentry_reallyFree (emarker);
4033 }
4034
4035 wasDestroyed = TRUE;
4036}
4037
4038uentry
4039uentry_makeElipsisMarker (void)
4040{
4041 if (emarker == NULL)
4042 {
4043 emarker = uentry_alloc ();
4044
4045 emarker->ukind = KELIPSMARKER;
4046 emarker->uname = cstring_makeLiteral ("...");
4047 emarker->utype = ctype_elipsMarker;
4048 emarker->sref = sRef_undefined;
4049 emarker->storageclass = SCNONE;
4050 emarker->used = FALSE;
4051 emarker->lset = FALSE;
4052 emarker->info = NULL;
4053
4054 uentry_setSpecDef (emarker, fileloc_undefined);
4055 emarker->uses = filelocList_new ();
4056 emarker->isPrivate = FALSE;
4057 emarker->hasNameError = FALSE;
4058 }
4059
4060 /*@ignore@*/ return (emarker); /*@end@*/
4061}
4062
4063/*
4064** comparisons
4065*/
4066
4067bool
4068uentry_equiv (uentry p1, uentry p2)
4069{
4070 if (uentry_compare (p1, p2) != 0)
4071 {
4072 return FALSE;
4073 }
4074 else
4075 {
4076 return TRUE;
4077 }
4078}
4079
4080int
4081uentry_xcomparealpha (uentry *p1, uentry *p2)
4082{
4083 int res;
4084
4085 if ((res = uentry_compare (*p1, *p2)) == 0) {
4086 if ((*p1 != NULL) && (*p2 != NULL)) {
4087 res = cstring_compare ((*p1)->uname,
4088 (*p2)->uname);
4089 }
4090 }
4091
4092 return res;
4093}
4094
4095int
4096uentry_xcompareuses (uentry *p1, uentry *p2)
4097{
4098 uentry u1 = *p1;
4099 uentry u2 = *p2;
4100
4101 if (uentry_isValid (u1))
4102 {
4103 if (uentry_isValid (u2))
4104 {
4105 return (-1 * int_compare (filelocList_size (u1->uses),
4106 filelocList_size (u2->uses)));
4107 }
4108 else
4109 {
4110 return 1;
4111 }
4112 }
4113 else
4114 {
4115 if (uentry_isValid (u2))
4116 {
4117 return -1;
4118 }
4119 else
4120 {
4121 return 0;
4122 }
4123 }
4124}
4125
4126int
4127uentry_compareStrict (uentry v1, uentry v2)
4128{
4129 COMPARERETURN (uentry_compare (v1, v2));
4130
4131 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4132 {
4133 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4134 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4135 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4136 }
4137
4138 return 0;
4139}
4140
4141int
4142uentry_compare (uentry u1, uentry u2)
4143{
4144 if (u1 == u2) return 0;
4145
4146 if (uentry_isInvalid (u1)) return -1;
4147 if (uentry_isInvalid (u2)) return 1;
4148
4149 INTCOMPARERETURN (u1->ukind, u2->ukind);
4150 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4151 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
616915dd 4152 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4153
4154 switch (u1->ukind)
4155 {
4156 case KINVALID:
4157 case KELIPSMARKER:
4158 /* bug detected by lclint:
4159 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4160 */
4161 return 0;
4162 case KENUMCONST:
4163 case KCONST:
b9904f57 4164 return (multiVal_compare (uentry_getConstantValue (u1),
4165 uentry_getConstantValue (u2)));
616915dd 4166 case KSTRUCTTAG:
4167 case KUNIONTAG:
4168 case KENUMTAG:
4169 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4170 case KITER:
4171 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4172 uentry_accessType (u2)));
4173 return (uentryList_compareParams (uentry_getParams (u1),
4174 uentry_getParams (u2)));
4175 case KENDITER:
4176 return (typeIdSet_compare (uentry_accessType (u1),
4177 uentry_accessType (u2)));
4178 case KFCN:
28bf4b0b 4179 /*
4180 ** Functions are never equivalent
4181 */
4182
b7e84605 4183 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
28bf4b0b 4184 {
4185 return -1;
4186 }
4187 else
4188 {
4189 return 1;
4190 }
4191 case KVAR:
4192
4193 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4194 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4195 sRef_getOrigAliasKind (u2->sref)));
4196 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4197 sRef_getOrigExKind (u2->sref)));
616915dd 4198 COMPARERETURN (generic_compare (u1->info->var->checked,
4199 u2->info->var->checked));
4200 COMPARERETURN (generic_compare (u1->info->var->defstate,
4201 u2->info->var->defstate));
4202 return (generic_compare (u1->info->var->nullstate,
4203 u2->info->var->nullstate));
4204 case KDATATYPE:
4205 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4206 u2->info->datatype->type));
4207 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4208 u2->info->datatype->mut));
4209 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4210 }
4211
4212 BADEXIT;
4213}
4214
4215/*
4216** library format:
4217**
4218** all entries are: <type>[@<info>]*#<name>
4219**
4220** info depends on kind:
4221*/
4222
4223static void
4224advanceField (char **s)
4225{
28bf4b0b 4226 reader_checkChar (s, '@');
616915dd 4227}
4228
4229static void
4230advanceName (char **s)
4231{
28bf4b0b 4232 reader_checkChar (s, '#');
616915dd 4233}
4234
4235static vkind
4236vkind_fromInt (int i)
4237{
4238 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4239 {
4240 llbuglit ("vkind_fromInt: out of range");
4241 }
4242
4243 return (vkind)i;
4244}
4245
4246static uentry
4247 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4248 typeIdSet access, nstate nullstate,
4249 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4250{
4251 uentry e = uentry_alloc ();
4252
4253 e->ukind = KCONST;
4254 e->uname = name;
4255 e->utype = ct;
4256 e->sref = sRef_makeConst (ct);
4257
4258 sRef_setNullState (e->sref, nullstate, loc);
4259 e->storageclass = SCNONE;
4260
4261 if (fileloc_isSpec (loc))
4262 {
4263 e->whereSpecified = loc;
4264 e->whereDeclared = fileloc_undefined;
4265 }
4266 else
4267 {
4268 e->whereSpecified = fileloc_undefined;
4269 e->whereDeclared = loc;
4270 }
4271
4272 e->whereDefined = fileloc_undefined;
4273 e->uses = filelocList_new ();
4274 e->isPrivate = FALSE;
4275 e->hasNameError = FALSE;
4276
4277 e->used = FALSE;
4278 e->lset = FALSE;
4279
28bf4b0b 4280 e->warn = warnClause_undefined; /*@i452@*/
4281
616915dd 4282 e->info = (uinfo) dmalloc (sizeof (*e->info));
4283 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
616915dd 4284 e->info->uconst->access = access;
4285
b9904f57 4286 uentry_setConstantValue (e, m);
616915dd 4287 sRef_storeState (e->sref);
4288
4289 return (e);
4290}
4291
4292static /*@only@*/ uentry
4293 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4294 sstate defstate, nstate isnull, alkind aliased,
4295 exkind exp, chkind checked,
4296 /*@only@*/ fileloc loc)
4297{
4298 uentry e = uentry_alloc ();
4299
4300 e->ukind = KVAR;
4301 e->uname = name;
4302 e->utype = ct;
4303 e->storageclass = SCNONE;
4304
4305 e->sref = sRef_makeType (ct);
4306 sRef_setNullState (e->sref, isnull, loc);
4307
4308 e->whereDefined = fileloc_undefined;
4309
4310 if (fileloc_isSpec (loc))
4311 {
4312 e->whereSpecified = loc;
4313 e->whereDeclared = fileloc_undefined;
4314 }
4315 else
4316 {
4317 e->whereSpecified = fileloc_undefined;
4318 e->whereDeclared = loc;
4319 }
4320
4321 e->isPrivate = FALSE;
4322 e->hasNameError = FALSE;
4323
4324 e->used = FALSE;
4325 e->lset = FALSE;
4326
4327 e->uses = filelocList_new ();
28bf4b0b 4328 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4329
4330 e->info = (uinfo) dmalloc (sizeof (*e->info));
4331 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4332 e->info->var->kind = kind;
4333 e->info->var->checked = checked;
4334 e->info->var->defstate = defstate;
4335
4336 sRef_setDefState (e->sref, defstate, loc);
4337
4338 e->info->var->nullstate = sRef_getNullState (e->sref);
4339
4340 sRef_setExKind (e->sref, exp, loc);
4341 sRef_setAliasKind (e->sref, aliased, loc);
4342
4343 sRef_storeState (e->sref);
4344
4345 /*DRL ADDED 9-1-2000 */
4346 e->info->var->bufinfo = NULL;
4347
4348 return (e);
4349}
4350
4351static /*@only@*/ uentry
28bf4b0b 4352uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
616915dd 4353 ynm mut, ctype rtype, alkind ak, exkind exp,
4354 sstate defstate, nstate isnull,
4355 /*@only@*/ fileloc loc)
4356{
4357 uentry e = uentry_alloc ();
4358
4359 e->ukind = KDATATYPE;
4360 /* e->shallowCopy = FALSE; */
4361 e->uname = name;
4362 e->utype = ct;
4363 e->storageclass = SCNONE;
4364 e->sref = sRef_makeUnknown ();
28bf4b0b 4365 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
616915dd 4366
4367 /*
4368 ** This is only setting null state. (I think?)
4369 */
4370
4371 if (ctype_isUA (ct))
4372 {
4373 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4374
4375 if (uentry_isValid (te))
4376 {
4377 sRef_setStateFromUentry (e->sref, te);
4378 }
4379 else
4380 {
4381 /* problem for recursive type definitions */
4382 }
4383 }
4384
4385 sRef_setAliasKind (e->sref, ak, loc);
4386 sRef_setExKind (e->sref, exp, loc);
4387
4388 sRef_setDefState (e->sref, defstate, loc);
4389
28bf4b0b 4390 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
616915dd 4391 {
4392 isnull = NS_ABSNULL;
4393 }
4394
28bf4b0b 4395 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
616915dd 4396 sRef_mergeNullState (e->sref, isnull);
4397
4398 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4399
4400 if (fileloc_isSpec (loc))
4401 {
4402 e->whereSpecified = loc;
4403 e->whereDeclared = fileloc_undefined;
4404 }
4405 else
4406 {
4407 e->whereSpecified = fileloc_undefined;
4408 e->whereDeclared = loc;
4409 }
4410
4411 e->isPrivate = FALSE;
4412 e->hasNameError = FALSE;
4413
28bf4b0b 4414 e->warn = warnClause_undefined; /*@i452@*/
4415
616915dd 4416 e->used = FALSE;
4417 e->lset = FALSE;
4418 e->uses = filelocList_new ();
4419
4420 e->info = (uinfo) dmalloc (sizeof (*e->info));
4421 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
28bf4b0b 4422 e->info->datatype->abs = abstract;
616915dd 4423 e->info->datatype->mut = mut;
4424 e->info->datatype->type = rtype;
28bf4b0b 4425
4426 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
616915dd 4427 sRef_storeState (e->sref);
28bf4b0b 4428 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
616915dd 4429
4430 return (e);
4431}
4432
4433# ifndef NOLCL
4434static void uentry_setHasGlobs (uentry ue)
4435{
4436 llassert (uentry_isFunction (ue));
4437
4438 ue->info->fcn->hasGlobs = TRUE;
4439}
4440
4441static void uentry_setHasMods (uentry ue)
4442{
4443 llassert (uentry_isFunction (ue));
4444
4445 ue->info->fcn->hasMods = TRUE;
4446}
4447# endif
4448
4449bool uentry_hasGlobs (uentry ue)
4450{
4451 if (uentry_isFunction (ue))
4452 {
4453 return (ue->info->fcn->hasGlobs);
4454 }
4455
4456 return FALSE;
4457}
4458
28bf4b0b 4459bool uentry_hasStateClauseList (uentry ue)
616915dd 4460{
28bf4b0b 4461 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
616915dd 4462}
4463
ccf0a4a8 4464bool uentry_hasConditions (uentry ue)
4465{
4466 return (uentry_isFunction (ue)
4467 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4468 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4469}
4470
28bf4b0b 4471stateClauseList uentry_getStateClauseList (uentry ue)
616915dd 4472{
28bf4b0b 4473 if (!uentry_isFunction (ue))
4474 {
4475 llassert (uentry_isFunction (ue));
4476 return stateClauseList_undefined;
4477 }
4478
4479 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
616915dd 4480 return ue->info->fcn->specclauses;
4481}
4482
4483bool uentry_hasMods (uentry ue)
4484{
4485 if (uentry_isFunction (ue))
4486 {
4487 return (ue->info->fcn->hasMods);
4488 }
4489
4490 return FALSE;
4491}
4492
4493static uentry
4494 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4495 typeIdSet access,
4496 bool hasGlobs, /*@only@*/ globSet globs,
4497 bool hasMods, /*@only@*/ sRefSet mods,
4498 alkind ak, exkind exp,
4499 sstate defstate, nstate isnull,
4500 exitkind exitCode,
4501 specCode sCode,
4502 qual nullPred,
28bf4b0b 4503 /*@only@*/ stateClauseList specclauses,
4504 /*@only@*/ warnClause warnclause,
616915dd 4505 /*@only@*/ fileloc loc)
4506{
4507 uentry e = uentry_alloc ();
4508 ctype ret;
4509
4510 /* e->shallowCopy = FALSE; */
4511 e->ukind = KFCN;
4512 e->uname = name;
4513 e->utype = ct;
4514 e->storageclass = SCNONE;
4515
4516 if (ctype_isFunction (ct))
4517 {
28bf4b0b 4518 ret = ctype_getReturnType (ct);
616915dd 4519 }
4520 else
4521 {
4522 if (ctype_isKnown (ct))
4523 {
4524 llbug (message ("not function: %s", ctype_unparse (ct)));
4525 }
4526
4527 ret = ctype_unknown;
4528 }
4529
4530 e->sref = sRef_makeType (ret);
4531
4532 if (ctype_isUA (ret))
4533 {
4534 sRef_setStateFromType (e->sref, ret);
4535 }
4536
4537 sRef_setDefined (e->sref, loc);
4538 sRef_setNullState (e->sref, isnull, loc);
4539
4540 sRef_setAliasKind (e->sref, ak, loc);
4541 sRef_setExKind (e->sref, exp, loc);
4542 sRef_setDefState (e->sref, defstate, loc);
4543
4544 e->whereSpecified = loc;
4545 e->whereDefined = fileloc_undefined;
4546
4547 e->isPrivate = FALSE;
4548 e->hasNameError = FALSE;
4549
4550 e->used = FALSE;
4551 e->lset = FALSE;
4552 e->uses = filelocList_new ();
28bf4b0b 4553 e->warn = warnclause;
616915dd 4554
4555 e->info = (uinfo) dmalloc (sizeof (*e->info));
4556 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4557
4558 e->info->fcn->exitCode = exitCode;
4559 e->info->fcn->specialCode = sCode;
4560 e->info->fcn->nullPred = nullPred;
4561 e->info->fcn->access = access;
4562
4563 e->info->fcn->specclauses = specclauses;
4564 e->info->fcn->hasGlobs = hasGlobs;
4565 e->info->fcn->globs = globs;
4566
4567 e->info->fcn->hasMods = hasMods;
4568 e->info->fcn->mods = mods;
4569
4570 e->info->fcn->defparams = uentryList_undefined;
4571 e->whereDeclared = fileloc_undefined;
4572
4573 sRef_storeState (e->sref);
4574
4575 /*drl 111 30 2000*/
4576 e->info->fcn->preconditions = NULL;
4577 /* end drl */
4578
4579 /*drl 12 28 2000*/
4580 e->info->fcn->postconditions = NULL;
4581 /* end drl */
4582
4583 return (e);
4584}
4585
4586static /*@only@*/ uentry
4587 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4588 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4589{
4590 uentry e = uentry_alloc ();
4591
4592 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4593 {
4594 llbuglit ("uentry_makeTagBase: not a tag type");
4595 }
4596
4597 /* e->shallowCopy = FALSE; */
4598 e->ukind = tagkind;
4599 e->uname = name;
4600 e->utype = ct;
4601 e->sref = sRef_makeUnknown ();
4602 e->storageclass = SCNONE;
4603
4604 if (fileloc_isSpec (loc))
4605 {
4606 e->whereSpecified = loc;
4607 e->whereDeclared = fileloc_undefined;
4608 }
4609 else
4610 {
4611 e->whereDeclared = loc;
4612 e->whereSpecified = fileloc_undefined;
4613 }
4614
4615 e->whereDefined = fileloc_undefined;
4616
4617 e->isPrivate = FALSE;
4618 e->hasNameError = FALSE;
4619
4620 e->used = FALSE;
4621 e->lset = FALSE;
4622 e->uses = filelocList_new ();
28bf4b0b 4623 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4624
4625 e->info = (uinfo) dmalloc (sizeof (*e->info));
4626 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4627 e->info->datatype->abs = NO;
4628 e->info->datatype->mut = MAYBE;
4629 e->info->datatype->type = rtype;
4630
4631 sRef_storeState (e->sref);
4632
4633 return (e);
4634}
4635
4636static uentry
4637 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4638 ctype ct, /*@only@*/ fileloc loc)
4639{
4640 uentry e = uentry_alloc ();
4641
4642 /* e->shallowCopy = FALSE; */
4643 e->ukind = KITER;
4644 e->uname = name;
4645 e->utype = ct;
4646 e->sref = sRef_makeUnknown ();
4647 e->storageclass = SCNONE;
4648
4649 if (fileloc_isSpec (loc))
4650 {
4651 e->whereSpecified = loc;
4652 e->whereDeclared = fileloc_undefined;
4653 }
4654 else
4655 {
4656 e->whereDeclared = loc;
4657 e->whereSpecified = fileloc_undefined;
4658 }
4659
4660 e->whereDefined = fileloc_undefined;
4661
4662 e->isPrivate = FALSE;
4663 e->hasNameError = FALSE;
4664
4665 e->used = FALSE;
4666 e->lset = FALSE;
4667 e->uses = filelocList_new ();
28bf4b0b 4668 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4669
4670 e->info = (uinfo) dmalloc (sizeof (*e->info));
4671 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4672 e->info->iter->access = access;
4673 e->info->iter->mods = sRefSet_undefined;
4674 e->info->iter->globs = globSet_undefined;
4675
4676 sRef_storeState (e->sref);
4677 return (e);
4678}
4679
4680static uentry
4681 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4682 /*@only@*/ fileloc loc)
4683{
4684 uentry e = uentry_alloc ();
4685
4686 /* e->shallowCopy = FALSE; */
4687 e->ukind = KENDITER;
4688 e->storageclass = SCNONE;
4689 e->uname = name;
4690 e->utype = ctype_unknown;
4691 e->sref = sRef_makeUnknown ();
4692
4693 if (fileloc_isSpec (loc))
4694 {
4695 e->whereSpecified = loc;
4696 e->whereDeclared = fileloc_undefined;
4697 }
4698 else
4699 {
4700 e->whereDeclared = loc;
4701 e->whereSpecified = fileloc_undefined;
4702 }
4703
4704 e->whereDefined = fileloc_undefined;
4705
4706 e->isPrivate = FALSE;
4707 e->hasNameError = FALSE;
4708
4709 e->used = FALSE;
4710 e->lset = FALSE;
4711 e->uses = filelocList_new ();
28bf4b0b 4712 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4713
4714 e->info = (uinfo) dmalloc (sizeof (*e->info));
4715 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4716 e->info->enditer->access = access;
4717 sRef_storeState (e->sref);
4718
4719 return (e);
4720}
4721
4722void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4723{
4724 /* should save u */
4725/*@-mustfree@*/
4726}
4727/*@=mustfree@*/
4728
4729/*@only@*/ uentry
4730uentry_undump (ekind kind, fileloc loc, char **s)
4731{
4732 uentry ue;
4733
28bf4b0b 4734 DPRINTF (("Uentry undump: %s", *s));
4735
616915dd 4736 if (**s == '!')
4737 {
28bf4b0b 4738 reader_checkChar (s, '!');
4739 reader_checkChar (s, '.');
616915dd 4740 ue = uentry_makeElipsisMarker ();
4741 }
4742 else
4743 {
4744 ctype ct = ctype_undump (s);
4745 cstring name;
4746
4747 switch (kind)
4748 {
4749 case KVAR:
4750 {
4751 vkind tkind;
4752 sstate defstate;
4753 nstate isnull;
4754 alkind aliased;
4755 exkind exp;
4756 chkind checked;
4757
28bf4b0b 4758 reader_checkChar (s, '|');
616915dd 4759
28bf4b0b 4760 if (reader_optCheckChar (s, '@'))
616915dd 4761 {
28bf4b0b 4762 tkind = vkind_fromInt (reader_getInt (s));
4763 reader_checkChar (s, '|');
616915dd 4764 }
4765 else
4766 {
4767 tkind = VKPARAM;
4768 }
4769
28bf4b0b 4770 if (reader_optCheckChar (s, '$'))
616915dd 4771 {
4772 defstate = SS_UNKNOWN;
4773 isnull = NS_UNKNOWN;
4774 aliased = AK_IMPTEMP;
4775 exp = XO_UNKNOWN;
4776 checked = CH_UNKNOWN;
4777 }
28bf4b0b 4778 else if (reader_optCheckChar (s, '&'))
616915dd 4779 {
4780 defstate = SS_DEFINED;
4781 isnull = NS_UNKNOWN;
4782 aliased = AK_IMPTEMP;
4783 exp = XO_UNKNOWN;
4784 checked = CH_UNKNOWN;
4785 }
28bf4b0b 4786 else if (reader_optCheckChar (s, '^'))
616915dd 4787 {
4788 defstate = SS_UNKNOWN;
4789 isnull = NS_UNKNOWN;
4790 aliased = AK_IMPTEMP;
4791 exp = XO_UNKNOWN;
4792 checked = CH_UNKNOWN;
4793 }
4794 else
4795 {
28bf4b0b 4796 defstate = sstate_fromInt (reader_getInt (s));
4797 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4798 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
616915dd 4799
28bf4b0b 4800 if (reader_optCheckChar (s, '&'))
616915dd 4801 {
4802 exp = XO_UNKNOWN;
4803 checked = CH_UNKNOWN;
4804 }
4805 else
4806 {
28bf4b0b 4807 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4808 advanceField (s); checked = (chkind) (reader_getInt (s));
616915dd 4809 }
4810 }
4811
4812 advanceName (s);
28bf4b0b 4813 name = reader_getStringWord (s);
616915dd 4814
28bf4b0b 4815 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4816
616915dd 4817 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4818 isnull, aliased, exp,
4819 checked, fileloc_copy (loc));
4820 }
4821 break;
4822 case KDATATYPE:
4823 {
28bf4b0b 4824 ynm abstract;
616915dd 4825 ynm mut;
4826 ctype rtype;
4827 sstate defstate;
4828 nstate isnull;
4829 alkind aliased;
4830 exkind exp;
4831
28bf4b0b 4832 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4833 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4834 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4835 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4836 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4837 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
616915dd 4838 advanceField (s); rtype = ctype_undump (s);
4839 advanceName (s);
28bf4b0b 4840 name = reader_getStringWord (s);
4841 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4842 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
616915dd 4843 aliased, exp, defstate, isnull,
4844 fileloc_copy (loc));
4845 }
4846 break;
4847 case KFCN:
4848 {
4849 alkind ak;
4850 exkind exp;
4851 sstate defstate;
4852 nstate isnull;
4853 exitkind exitCode;
4854 specCode specc;
4855 qual nullPred;
4856 typeIdSet access;
4857 bool hasGlobs;
4858 globSet globs;
4859 bool hasMods;
4860 sRefSet mods;
28bf4b0b 4861 stateClauseList specclauses = stateClauseList_undefined;
4862 warnClause warnclause = warnClause_undefined;
616915dd 4863
28bf4b0b 4864 if (reader_optCheckChar (s, '$'))
616915dd 4865 {
4866 defstate = SS_DEFINED;
4867 isnull = NS_UNKNOWN;
4868 exitCode = XK_UNKNOWN;
4869 specc = SPC_NONE;
28bf4b0b 4870 nullPred = qual_createUnknown ();
616915dd 4871 }
4872 else
4873 {
28bf4b0b 4874 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4875 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4876 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4877 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4878 advanceField (s); nullPred = qual_undump (s);
616915dd 4879 }
4880
28bf4b0b 4881 if (reader_optCheckChar (s, '$'))
616915dd 4882 {
4883 hasGlobs = FALSE;
4884 globs = globSet_undefined;
4885 hasMods = FALSE;
4886 mods = sRefSet_undefined;
4887 }
28bf4b0b 4888 else if (reader_optCheckChar (s, '^'))
616915dd 4889 {
4890 hasGlobs = TRUE;
4891 globs = globSet_undefined;
4892 hasMods = TRUE;
4893 mods = sRefSet_undefined;
4894 }
4895 else
4896 {
28bf4b0b 4897 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
616915dd 4898 advanceField (s); globs = globSet_undump (s);
28bf4b0b 4899 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
616915dd 4900 advanceField (s); mods = sRefSet_undump (s);
4901 }
4902
28bf4b0b 4903 if (reader_optCheckChar (s, '$'))
616915dd 4904 {
4905 ak = AK_UNKNOWN;
4906 exp = XO_UNKNOWN;
4907 }
4908 else
4909 {
28bf4b0b 4910 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4911 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
616915dd 4912 }
4913
4914 advanceField (s); access = typeIdSet_undump (s);
4915
28bf4b0b 4916 /*
4917 ** Optional clauses: Start with @<code>:
4918 */
4919
4920 while (reader_optCheckChar (s, '@'))
616915dd 4921 {
28bf4b0b 4922 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4923 {
4924 reader_checkChar (s, ':');
4925 warnclause = warnClause_undump (s);
4926 }
4927 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4928 {
4929 reader_checkChar (s, ':');
4930 specclauses = stateClauseList_undump (s);
4931 }
4932 else
4933 {
4934 BADBRANCH;
4935 }
616915dd 4936 }
4937
28bf4b0b 4938 advanceName (s); name = reader_getStringWord (s);
616915dd 4939
4940 ue = uentry_makeFunctionBase (name, ct, access,
4941 hasGlobs, globs,
4942 hasMods, mods,
4943 ak, exp, defstate, isnull,
4944 exitCode, specc, nullPred,
4945 specclauses,
28bf4b0b 4946 warnclause,
616915dd 4947 fileloc_copy (loc));
4948 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4949 }
4950 break;
4951 case KITER:
4952 {
4953 typeIdSet access;
4954
4955 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 4956 advanceName (s); name = reader_getStringWord (s);
616915dd 4957
4958 ue = uentry_makeIterBase (name, access, ct,
4959 fileloc_copy (loc));
4960 }
4961 break;
4962 case KENDITER:
4963 {
4964 typeIdSet access;
4965
4966 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 4967 advanceName (s); name = reader_getStringWord (s);
616915dd 4968
4969 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4970 }
4971 break;
4972 case KENUMCONST:
4973 case KCONST:
4974 {
4975 typeIdSet access;
4976 multiVal val;
4977 nstate nullstate;
4978
28bf4b0b 4979 if (reader_optCheckChar (s, '$'))
616915dd 4980 {
4981 val = multiVal_undefined;
4982 access = typeIdSet_undefined;
4983 nullstate = NS_UNKNOWN;
4984 }
4985 else
4986 {
4987 advanceField (s); val = multiVal_undump (s);
4988 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 4989 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
616915dd 4990 }
4991
28bf4b0b 4992 advanceName (s); name = reader_getStringWord (s);
616915dd 4993
4994 ue = uentry_makeConstantBase (name, ct, access,
4995 nullstate, fileloc_copy (loc), val);
4996 break;
4997 }
4998 case KSTRUCTTAG:
4999 case KUNIONTAG:
5000 case KENUMTAG:
5001 {
5002 ctype rtype;
5003
5004 advanceField (s); rtype = ctype_undump (s);
28bf4b0b 5005 advanceName (s); name = reader_getStringWord (s);
616915dd 5006 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5007 }
5008 break;
5009 case KINVALID:
5010 llcontbuglit ("uentry_undump: invalid");
5011 ue = uentry_undefined;
5012 break;
5013 case KELIPSMARKER:
5014 llcontbuglit ("uentry_undump: elips marker");
5015 ue = uentry_undefined;
5016 break;
5017 }
5018 }
5019
5020 return (ue);
5021}
5022
5023cstring
5024uentry_dump (uentry v)
5025{
5026 return (uentry_dumpAux (v, FALSE));
5027}
5028
5029cstring
5030uentry_dumpParam (uentry v)
5031{
5032 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5033 ("dump: %s", uentry_unparseFull (v)));
5034
5035 return (uentry_dumpAux (v, TRUE));
5036}
5037
5038static cstring
5039uentry_dumpAux (uentry v, bool isParam)
5040{
5041 llassert (uentry_isValid (v));
28bf4b0b 5042 llassert (!uentry_isGlobalMarker (v));
616915dd 5043
28bf4b0b 5044 DPRINTF (("Dump uentry: [%p]", v));
616915dd 5045 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
28bf4b0b 5046
616915dd 5047 switch (v->ukind)
5048 {
5049 case KINVALID:
5050 llcontbuglit ("uentry_dump: invalid entry");
5051 return cstring_undefined;
5052 case KELIPSMARKER:
5053 return (message ("!."));
5054 case KVAR:
5055 {
5056 cstring sdump;
5057 vkind vk = v->info->var->kind;
5058 sstate dss = sRef_getDefState (v->sref);
5059 nstate nst = sRef_getNullState (v->sref);
5060 alkind alk = sRef_getAliasKind (v->sref);
5061 exkind exk = sRef_getExKind (v->sref);
5062 chkind chk = v->info->var->checked;
5063
5064 DPRINTF (("Dumping var"));
5065
5066 if (dss == SS_UNKNOWN
5067 && nst == NS_UNKNOWN
5068 && alk == AK_IMPTEMP
5069 && exk == XO_UNKNOWN
5070 && chk == CH_UNKNOWN)
5071 {
5072 sdump = cstring_makeLiteral ("$");
5073 }
5074 else if (dss == SS_DEFINED
5075 && nst == NS_UNKNOWN
5076 && alk == AK_IMPTEMP
5077 && exk == XO_UNKNOWN
5078 && chk == CH_UNKNOWN)
5079 {
5080 sdump = cstring_makeLiteral ("&");
5081 }
5082 else if (dss == SS_UNKNOWN
5083 && nst == NS_UNKNOWN
5084 && alk == AK_UNKNOWN
5085 && exk == XO_UNKNOWN
5086 && chk == CH_UNKNOWN)
5087 {
5088 sdump = cstring_makeLiteral ("^");
5089 }
5090 else if (exk == XO_UNKNOWN
5091 && chk == CH_UNKNOWN)
5092 {
5093 sdump = message ("%d@%d@%d&",
5094 (int) dss,
5095 (int) nst,
5096 (int) alk);
5097 }
5098 else
5099 {
5100 sdump = message ("%d@%d@%d@%d@%d",
5101 (int) dss,
5102 (int) nst,
5103 (int) alk,
5104 (int) exk,
5105 (int) chk);
5106 }
5107
5108
5109 if (vk != VKPARAM)
5110 {
5111 return (message ("%q|@%d|%q#%s",
5112 ctype_dump (v->utype),
5113 (int) vk,
5114 sdump,
5115 isParam ? cstring_undefined : v->uname));
5116 }
5117 else
5118 {
5119 return (message ("%q|%q#%s",
5120 ctype_dump (v->utype),
5121 sdump,
5122 isParam ? cstring_undefined : v->uname));
5123 }
5124
5125 }
5126 case KDATATYPE:
28bf4b0b 5127 /*
5128 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5129 uentry_unparse (v),
5130 exkind_unparse (sRef_getExKind (v->sref)),
5131 ctype_unparse (v->utype), (int) v->utype));
5132 */
5133
616915dd 5134 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5135 ctype_dump (v->utype),
5136 ynm_unparseCode (v->info->datatype->abs),
5137 ynm_unparseCode (v->info->datatype->mut),
5138 (int) sRef_getDefState (v->sref),
5139 (int) sRef_getNullState (v->sref),
5140 (int) sRef_getAliasKind (v->sref),
5141 (int) sRef_getExKind (v->sref),
5142 ctype_dump (v->info->datatype->type),
5143 v->uname));
5144 case KFCN:
5145 {
28bf4b0b 5146 cstring sdump, gdump, adump, xdump;
616915dd 5147 alkind alk = sRef_getAliasKind (v->sref);
5148 exkind exk = sRef_getExKind (v->sref);
5149
5150 if (sRef_getDefState (v->sref) == SS_DEFINED
5151 && !nstate_isKnown (sRef_getNullState (v->sref))
5152 && !exitkind_isKnown (v->info->fcn->exitCode)
5153 && v->info->fcn->specialCode == SPC_NONE
28bf4b0b 5154 && qual_isUnknown (v->info->fcn->nullPred))
616915dd 5155 {
5156 sdump = cstring_makeLiteral ("$");
5157 }
5158 else
5159 {
28bf4b0b 5160 sdump = message ("@%d@%d@%d@%d@%x",
616915dd 5161 (int) sRef_getDefState (v->sref),
5162 (int) sRef_getNullState (v->sref),
5163 (int) v->info->fcn->exitCode,
5164 (int) v->info->fcn->specialCode,
28bf4b0b 5165 qual_dump (v->info->fcn->nullPred));
616915dd 5166 }
5167
5168 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5169 {
5170 gdump = cstring_makeLiteral ("$");
5171 }
5172 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5173 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5174 {
5175 gdump = cstring_makeLiteral ("^");
5176 }
5177 else
5178 {
5179 gdump = message ("@%s@%q@%s@%q",
5180 bool_dump (uentry_hasGlobs (v)),
5181 globSet_dump (uentry_getGlobs (v)),
5182 bool_dump (uentry_hasMods (v)),
5183 sRefSet_dump (uentry_getMods (v)));
5184 }
5185
5186 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5187 {
5188 adump = cstring_makeLiteral ("$");
5189 }
5190 else
5191 {
5192 adump = message ("@%d@%d", (int) alk, (int) exk);
5193 }
5194
28bf4b0b 5195 xdump = cstring_undefined;
5196
5197 if (uentry_hasWarning (v))
616915dd 5198 {
28bf4b0b 5199 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
616915dd 5200 }
28bf4b0b 5201
5202 if (uentry_hasStateClauseList (v))
616915dd 5203 {
28bf4b0b 5204 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
616915dd 5205 }
28bf4b0b 5206
5207 return (message ("%q%q%q%q@%q%q#%s",
5208 ctype_dump (v->utype),
5209 sdump,
5210 gdump,
5211 adump,
5212 typeIdSet_dump (uentry_accessType (v)),
5213 xdump,
5214 v->uname));
616915dd 5215 }
5216 case KITER:
5217 return (message ("%q@%q#%s",
5218 ctype_dump (v->utype),
5219 typeIdSet_dump (v->info->iter->access),
5220 v->uname));
5221 case KENDITER:
5222 return (message ("%q@%q#%s",
5223 ctype_dump (v->utype),
5224 typeIdSet_dump (uentry_accessType (v)),
5225 v->uname));
5226 case KENUMCONST:
5227 case KCONST:
5228 {
5229 cstring sdump;
5230
b9904f57 5231 if (multiVal_isUnknown (uentry_getConstantValue (v))
616915dd 5232 && typeIdSet_isEmpty (uentry_accessType (v))
5233 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5234 {
5235 sdump = cstring_makeLiteral ("$");
5236 }
5237 else
5238 {
5239 sdump = message ("@%q@%q@%d",
b9904f57 5240 multiVal_dump (uentry_getConstantValue (v)),
616915dd 5241 typeIdSet_dump (uentry_accessType (v)),
5242 (int) sRef_getNullState (v->sref));
5243 }
5244
5245 return (message ("%q%q#%s",
5246 ctype_dump (v->utype),
5247 sdump,
5248 v->uname));
5249 }
5250 case KSTRUCTTAG:
5251 case KUNIONTAG:
5252 case KENUMTAG:
5253 return (message ("%q@%q#%s",
5254 ctype_dump (v->utype),
5255 ctype_dump (v->info->datatype->type), v->uname));
5256 }
5257
5258 BADEXIT;
5259}
5260
5261/*@only@*/ cstring
5262uentry_unparseAbbrev (uentry v)
5263{
5264 if (!uentry_isVariable (v))
5265 {
5266 llcontbuglit ("uentry_unparseAbbrev: not variable");
5267 return uentry_unparse (v);
5268 }
5269
5270 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5271}
5272
5273/*@only@*/ cstring
5274uentry_unparse (uentry v)
5275{
5276 cstring st;
5277
5278 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5279 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5280
5281 st = uentry_getName (v);
5282
5283 if (cstring_isDefined (st))
5284 {
5285 return (ctype_unparseDeclaration (v->utype, st));
5286 }
5287 else
5288 {
5289 cstring_free (st);
5290 return (cstring_copy (ctype_unparse (v->utype)));
5291 }
5292}
5293
5294/*@only@*/ cstring
5295uentry_unparseFull (uentry v)
5296{
5297 if (uentry_isUndefined (v))
5298 {
5299 return (cstring_makeLiteral ("<undefined>"));
5300 }
616915dd 5301 else
5302 {
28bf4b0b 5303 cstring res;
5304
5305 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5306 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5307 ctype_unparse (v->utype),
5308 fileloc_unparse (uentry_whereSpecified (v)),
5309 fileloc_unparse (uentry_whereDeclared (v)),
5310 fileloc_unparse (uentry_whereDefined (v)));
5311
5312 DPRINTF (("uentry: %s", res));
5313
5314 if (uentry_isDatatype (v))
5315 {
5316 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5317 res,
5318 ctype_unparse
5319 (ctype_isDefined (v->info->datatype->type)
5320 ? v->info->datatype->type : ctype_unknown),
5321 ynm_unparse (v->info->datatype->mut),
5322 ynm_unparse (v->info->datatype->abs),
5323 sRef_unparseState (v->sref));
5324 }
5325 else if (uentry_isFunction (v))
5326 {
5327 res = message ("%q / sref: %q / mods: %q / "
ba45e1e4 5328 "globs: %q / clauses: %q / pre: %q / post: %q",
28bf4b0b 5329 res,
5330 sRef_unparseFull (v->sref),
5331 sRefSet_unparse (v->info->fcn->mods),
5332 globSet_unparse (v->info->fcn->globs),
ba45e1e4 5333 stateClauseList_unparse (v->info->fcn->specclauses),
5334 functionConstraint_unparse (v->info->fcn->preconditions),
5335 functionConstraint_unparse (v->info->fcn->postconditions));
28bf4b0b 5336 }
5337 else if (uentry_isIter (v))
5338 {
5339 res = message ("%q / sref: %q",
5340 res,
5341 sRef_unparseFull (v->sref));
5342 }
5343 else if (uentry_isVariable (v))
5344 {
5345 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5346 res,
5347 sRef_unparseFull (v->sref),
5348 (int) v->info->var->kind,
5349 (int) v->info->var->defstate,
5350 (int) v->info->var->nullstate,
5351 (int) v->used);
5352 DPRINTF (("sref: [%p]", v->sref));
5353 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5354 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5355 }
b9904f57 5356 else if (uentry_isConstant (v))
5357 {
5358 res = message ("%q = %q",
5359 res, multiVal_unparse (uentry_getConstantValue (v)));
5360 }
28bf4b0b 5361 else
5362 {
5363 res = message ("%q :: %q", res, uentry_unparse (v));
5364 }
5365
5366 return res;
616915dd 5367 }
5368}
5369
5370bool uentry_hasAccessType (uentry e)
5371{
5372 if (uentry_isValid (e))
5373 {
5374 switch (e->ukind)
5375 {
5376 case KITER:
5377 return (!typeIdSet_isEmpty (e->info->iter->access));
5378 case KENDITER:
5379 return (!typeIdSet_isEmpty (e->info->enditer->access));
5380 case KFCN:
5381 return (!typeIdSet_isEmpty (e->info->fcn->access));
5382 case KENUMCONST:
5383 case KCONST:
5384 return (!typeIdSet_isEmpty (e->info->uconst->access));
5385 default:
5386 return FALSE;
5387 }
5388 }
5389
5390 return FALSE;
5391}
5392
5393typeIdSet uentry_accessType (uentry e)
5394{
5395 if (uentry_isValid (e))
5396 {
5397 switch (e->ukind)
5398 {
5399 case KITER:
5400 return (e->info->iter->access);
5401 case KENDITER:
5402 return (e->info->enditer->access);
5403 case KFCN:
5404 return (e->info->fcn->access);
5405 case KENUMCONST:
5406 case KCONST:
5407 return (e->info->uconst->access);
5408 default:
5409 break;
5410 }
5411 }
5412
5413 return typeIdSet_undefined;
5414}
5415
5416bool
5417uentry_isVariable (uentry e)
5418{
5419 return (uentry_isVar (e));
5420}
5421
5422bool
5423uentry_isSpecified (uentry e)
5424{
5425 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5426}
5427
5428static bool
5429uentry_isReallySpecified (uentry e)
5430{
5431 return (uentry_isValid (e)
5432 && fileloc_isRealSpec (e->whereSpecified));
5433}
5434
5435bool
5436uentry_isVar (uentry e)
5437{
5438 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5439}
5440
5441bool
5442uentry_isFakeTag (uentry e)
5443{
5444 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5445}
5446
5447bool
5448uentry_isDatatype (uentry e)
5449{
5450 return (!uentry_isUndefined (e) &&
5451 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5452 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5453}
5454
5455void
5456uentry_setAbstract (uentry e)
5457{
5458 typeId oldid;
5459
5460 llassert (uentry_isDatatype (e)
5461 && (ynm_isMaybe (e->info->datatype->abs)));
5462
5463 oldid = ctype_typeId (e->info->datatype->type);
5464 e->info->datatype->abs = YES;
5465 e->info->datatype->type = ctype_createAbstract (oldid);
5466}
5467
5468void
5469uentry_setConcrete (uentry e)
5470{
5471 llassert (uentry_isDatatype (e)
5472 && (ynm_isMaybe (e->info->datatype->abs)));
5473
5474 e->info->datatype->abs = NO;
5475}
5476
5477bool
5478uentry_isAbstractDatatype (uentry e)
5479{
5480 return (uentry_isDatatype (e)
5481 && (ynm_isOn (e->info->datatype->abs)));
5482}
5483
5484bool
5485uentry_isMaybeAbstract (uentry e)
5486{
5487 return (uentry_isDatatype (e)
5488 && (ynm_isMaybe (e->info->datatype->abs)));
5489}
5490
5491bool
5492uentry_isMutableDatatype (uentry e)
5493{
5494 bool res = uentry_isDatatype (e)
5495 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5496
5497 return res;
5498}
5499
5500bool
5501uentry_isRefCountedDatatype (uentry e)
5502{
5503 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5504}
5505
5506bool
5507uentry_isParam (uentry u)
5508{
5509 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5510 || u->info->var->kind == VKYIELDPARAM));
5511}
5512
5513bool
5514uentry_isExpandedMacro (uentry u)
5515{
5516 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5517}
5518
5519bool
5520uentry_isSefParam (uentry u)
5521{
5522 return (uentry_isVariable (u)
5523 && (u->info->var->kind == VKSEFPARAM
5524 || u->info->var->kind == VKREFSEFPARAM
5525 || u->info->var->kind == VKSEFRETPARAM
5526 || u->info->var->kind == VKREFSEFRETPARAM));
5527}
5528
5529bool
5530uentry_isRefParam (uentry u)
5531{
5532 return (uentry_isVariable (u)
5533 && (u->info->var->kind == VKREFPARAM
5534 || u->info->var->kind == VKREFYIELDPARAM
5535 || u->info->var->kind == VKREFSEFPARAM
5536 || u->info->var->kind == VKREFSEFRETPARAM));
5537}
5538
5539bool
5540uentry_isAnyParam (uentry u)
5541{
5542 return (uentry_isVariable (u)
5543 && ((u->info->var->kind == VKPARAM)
5544 || (u->info->var->kind == VKSEFPARAM)
5545 || (u->info->var->kind == VKYIELDPARAM)
5546 || (u->info->var->kind == VKRETPARAM)
5547 || (u->info->var->kind == VKSEFRETPARAM)));
5548}
5549
5550sstate
5551uentry_getDefState (uentry u)
5552{
5553 if (uentry_isValid (u))
5554 {
5555 return (sRef_getDefState (u->sref));
5556 }
5557 else
5558 {
5559 return (SS_UNKNOWN);
5560 }
5561}
5562
5563bool
5564uentry_isOut (uentry u)
5565{
5566 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5567 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5568}
5569
5570bool
5571uentry_isPartial (uentry u)
5572{
5573 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5574 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5575}
5576
5577bool
5578uentry_isStateSpecial (uentry u)
5579{
5580 return ((uentry_isVariable (u)
5581 && (u->info->var->defstate == SS_SPECIAL))
5582 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5583}
5584
5585exitkind uentry_getExitCode (uentry ue)
5586{
5587 if (uentry_isFunction (ue))
5588 {
5589 return ue->info->fcn->exitCode;
5590 }
5591 else
5592 {
5593 return XK_UNKNOWN;
5594 }
5595}
5596
28bf4b0b 5597qual uentry_nullPred (uentry u)
616915dd 5598{
5599 llassert (uentry_isRealFunction (u));
5600
5601 if (uentry_isFunction (u))
5602 {
5603 return (u->info->fcn->nullPred);
5604 }
5605 else
5606 {
28bf4b0b 5607 return qual_createUnknown ();
616915dd 5608 }
5609}
5610
28bf4b0b 5611/*
5612** Note for variables, this is checking the declared state, not the current state.
5613*/
5614
616915dd 5615bool
5616uentry_possiblyNull (uentry u)
5617{
5618 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5619 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5620}
5621
5622alkind
5623uentry_getAliasKind (uentry u)
5624{
5625 if (uentry_isValid (u))
5626 {
5627 return (sRef_getAliasKind (uentry_getSref (u)));
5628 }
5629 else
5630 {
5631 return AK_UNKNOWN;
5632 }
5633}
5634
5635exkind
5636uentry_getExpKind (uentry u)
5637{
5638 if (uentry_isValid (u))
5639 {
5640 return (sRef_getExKind (uentry_getSref (u)));
5641 }
5642 else
5643 {
5644 return XO_UNKNOWN;
5645 }
5646}
5647
5648bool
5649uentry_isIter (uentry e)
5650{
5651 return (!uentry_isUndefined (e) && e->ukind == KITER);
5652}
5653
5654bool
5655uentry_isEndIter (uentry e)
5656{
5657 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5658}
5659
5660bool
5661uentry_isRealFunction (uentry e)
5662{
5663 return (uentry_isFunction (e) ||
5664 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5665}
5666
5667bool
5668uentry_hasName (uentry e)
5669{
5670 if (uentry_isValid (e))
5671 {
5672 cstring s = e->uname;
5673
28bf4b0b 5674 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5675 || uentry_isFakeTag (e)));
616915dd 5676 }
5677 else
5678 {
5679 return FALSE;
5680 }
5681}
5682
28bf4b0b 5683/*
5684** Returns true for fake tags.
5685** This is used for dumping the library
5686*/
5687
616915dd 5688bool uentry_hasRealName (uentry e)
5689{
28bf4b0b 5690 return (uentry_isValid (e)
5691 && cstring_isNonEmpty (e->uname)
5692 && !uentry_isGlobalMarker (e));
616915dd 5693}
5694
5695
5696/*@observer@*/ globSet
5697uentry_getGlobs (uentry l)
5698{
5699 if (uentry_isInvalid (l))
5700 {
5701 return globSet_undefined;
5702 }
5703
5704 if (l->ukind != KFCN)
5705 {
5706 if (l->ukind != KITER && l->ukind != KENDITER)
5707 {
5708 if (l->ukind == KVAR)
5709 {
5710 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5711 uentry_unparse (l),
5712 ekind_unparse (l->ukind)));
5713 }
5714 else
5715 {
5716 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5717 uentry_unparse (l),
5718 ekind_unparse (l->ukind)));
5719 }
5720 }
5721 return globSet_undefined;
5722 }
5723
5724 return l->info->fcn->globs;
5725}
5726
5727/*@observer@*/ sRefSet
5728uentry_getMods (uentry l)
5729{
5730 llassert (uentry_isValid (l));
5731
5732 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5733 {
5734 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5735 return sRefSet_undefined;
5736 }
5737
5738 return l->info->fcn->mods;
5739}
5740
5741ekind
5742uentry_getKind (uentry e)
5743{
5744 llassert (uentry_isValid (e));
5745
5746 return (e->ukind);
5747}
5748
5749/*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5750{
b9904f57 5751 llassert (uentry_isEitherConstant (e));
5752 return (sRef_getValue (e->sref));
616915dd 5753}
5754
5755/*@observer@*/ uentryList
5756uentry_getParams (uentry l)
5757{
5758 if (uentry_isInvalid (l)) return uentryList_undefined;
5759
5760 switch (l->ukind)
5761 {
5762 case KFCN:
5763 case KITER:
5764 {
5765 ctype ct = l->utype;
5766
5767 if (ctype_isFunction (ct))
5768 {
5769 return (ctype_argsFunction (ct));
5770 }
5771 else
5772 {
5773 return uentryList_undefined;
5774 }
5775 }
5776 case KVAR:
5777 {
5778 ctype ct = l->utype;
5779
5780 llassert (ctype_isFunction (ct));
5781 return (ctype_argsFunction (ct));
5782 }
5783 BADDEFAULT;
5784 }
5785 BADEXIT;
5786}
5787
5788/*@observer@*/ cstring
5789uentry_rawName (uentry e)
5790{
5791 if (uentry_isValid (e))
5792 {
5793 return (e->uname);
5794 }
5795 else
5796 {
5797 return cstring_undefined;
5798 }
5799}
5800
5801static cstring
5802uentry_getOptName (uentry e)
5803{
5804 cstring s = uentry_getName (e);
5805
5806 if (cstring_isDefined (s))
5807 {
5808 s = cstring_appendChar (s, ' ');
5809 }
5810
5811 return s;
5812}
5813
5814/*@only@*/ cstring
5815uentry_getName (uentry e)
5816{
5817 cstring ret = cstring_undefined;
5818
5819 if (uentry_isValid (e))
5820 {
616915dd 5821 if (uentry_isAnyTag (e))
5822 {
28bf4b0b 5823 ret = fixTagName (e->uname);
616915dd 5824 }
5825 else if (uentry_isAnyParam (e))
5826 {
5827 ret = cstring_copy (fixParamName (e->uname));
5828 }
5829 else
5830 {
5831 ret = cstring_copy (e->uname);
5832 }
5833 }
5834
5835 return ret;
5836}
5837
28bf4b0b 5838cstring uentry_observeRealName (uentry e)
5839{
5840 cstring ret = cstring_undefined;
5841
5842 if (uentry_isValid (e))
5843 {
5844 if (uentry_isAnyTag (e))
5845 {
5846 if (isFakeTag (e->uname))
5847 {
5848 ret = cstring_undefined;
5849 }
5850 else
5851 {
5852 ret = plainTagName (e->uname);
5853 }
5854 }
5855 else if (uentry_isAnyParam (e))
5856 {
5857 ret = fixParamName (e->uname);
5858 }
5859 else
5860 {
5861 ret = e->uname;
5862 }
5863 }
5864
5865 return ret;
5866}
5867
616915dd 5868cstring uentry_getRealName (uentry e)
5869{
5870 if (uentry_isValid (e))
5871 {
5872 if (uentry_isAnyTag (e))
5873 {
5874 return (cstring_undefined);
5875 }
5876 else
5877 {
5878 return (e->uname);
5879 }
5880 }
5881 return cstring_undefined;
5882}
5883
5884ctype uentry_getType (uentry e)
5885{
5886 if (uentry_isValid (e))
5887 {
5888 return e->utype;
5889 }
5890 else
5891 {
5892 return ctype_unknown;
5893 }
5894}
5895
5896fileloc uentry_whereLast (uentry e)
5897{
5898 fileloc loc;
5899
5900 if (uentry_isInvalid (e))
5901 {
5902 return fileloc_undefined;
5903 }
5904
5905 loc = e->whereDefined;
5906
5907 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5908 {
5909 return loc;
5910 }
5911
5912 loc = uentry_whereDeclared (e);
5913
5914 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5915 {
5916 return loc;
5917 }
5918
5919 loc = uentry_whereSpecified (e);
5920 return loc;
5921}
5922
5923fileloc uentry_whereEither (uentry e)
5924{
5925 if (uentry_isInvalid (e)) return fileloc_undefined;
5926
5927 if (fileloc_isDefined (e->whereDefined)
5928 && !fileloc_isExternal (e->whereDefined))
5929 {
5930 return e->whereDefined;
5931 }
5932 else if (fileloc_isDefined (e->whereDeclared))
5933 {
5934 return e->whereDeclared;
5935 }
5936 else
5937 {
5938 return e->whereSpecified;
5939 }
5940}
5941
5942fileloc uentry_whereSpecified (uentry e)
5943{
5944 if (uentry_isInvalid (e)) return fileloc_undefined;
5945
5946 return (e->whereSpecified);
5947}
5948
5949fileloc uentry_whereDefined (uentry e)
5950{
5951 if (uentry_isInvalid (e)) return fileloc_undefined;
5952
5953 return (e->whereDefined);
5954}
5955
5956fileloc uentry_whereDeclared (uentry e)
5957{
5958 if (uentry_isInvalid (e)) return fileloc_undefined;
5959
5960 return (e->whereDeclared);
5961}
5962
5963/*@observer@*/ fileloc
5964uentry_whereEarliest (uentry e)
5965{
5966 if (uentry_isInvalid (e)) return fileloc_undefined;
5967
5968 if (fileloc_isDefined (e->whereSpecified))
5969 {
5970 return (e->whereSpecified);
5971 }
5972 else if (fileloc_isDefined (e->whereDeclared))
5973 {
5974 return (e->whereDeclared);
5975 }
5976 else
5977 {
5978 return e->whereDefined;
5979 }
5980}
5981
5982void
5983uentry_setFunctionDefined (uentry e, fileloc loc)
5984{
5985 if (uentry_isValid (e))
5986 {
5987 llassert (uentry_isFunction (e));
5988
5989 if (fileloc_isUndefined (e->whereDeclared))
5990 {
5991 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5992 }
5993
5994 if (!fileloc_isDefined (e->whereDefined))
5995 {
5996 e->whereDefined = fileloc_update (e->whereDefined, loc);
5997 }
5998 }
5999}
6000
6001void
6002uentry_setDeclDef (uentry e, fileloc f)
6003{
6004 uentry_setDeclared (e, f);
6005
6006 if (!uentry_isFunction (e)
6007 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6008 {
6009 uentry_setDefined (e, f);
6010 }
6011}
6012
6013void
6014uentry_setDeclaredForce (uentry e, fileloc f)
6015{
6016 llassert (uentry_isValid (e));
6017 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6018}
6019
6020void
6021uentry_setDeclaredForceOnly (uentry e, fileloc f)
6022{
6023 llassert (uentry_isValid (e));
6024 fileloc_free (e->whereDeclared);
6025 e->whereDeclared = f;
6026}
6027
6028void
6029uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6030{
6031 fileloc oldloc;
6032
6033 llassert (uentry_isValid (e));
6034 oldloc = e->whereDeclared;
6035
6036 if (fileloc_isDefined (oldloc))
6037 {
6038 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6039 {
6040 e->whereDeclared = f;
6041 fileloc_free (oldloc);
6042 }
6043 else
6044 {
6045 fileloc_free (f);
6046 }
6047 }
6048 else
6049 {
6050 e->whereDeclared = f;
6051 fileloc_free (oldloc);
6052 }
6053}
6054
6055void
6056uentry_setDeclared (uentry e, fileloc f)
6057{
6058 fileloc oldloc;
6059
6060 llassert (uentry_isValid (e));
6061 oldloc = e->whereDeclared;
6062
6063 if (fileloc_isDefined (oldloc))
6064 {
6065 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6066 {
6067 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6068 }
6069 else
6070 {
6071 ;
6072 }
6073 }
6074 else
6075 {
6076 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6077 }
6078}
6079
6080void
6081uentry_clearDefined (uentry e)
6082{
6083 if (uentry_isValid (e))
6084 {
6085 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6086 }
6087}
6088
6089void
6090uentry_setDefined (uentry e, fileloc f)
6091{
6092 fileloc oldloc;
6093
6094 llassert (uentry_isValid (e));
6095 oldloc = e->whereDefined;
6096
6097 if (fileloc_isDefined (oldloc))
6098 {
6099 if (fileloc_isLib (oldloc)
6100 || fileloc_isImport (oldloc)
6101 || fileloc_isBuiltin (oldloc)
6102 || fileloc_isPreproc (oldloc))
6103 {
6104 e->whereDefined = fileloc_update (e->whereDefined, f);
6105 }
6106 else
6107 {
6108 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6109 {
6110 ; /* okay */
6111 }
6112 else
6113 {
6114 if (optgenerror (FLG_REDEF,
6115 message ("%s %q redefined",
6116 ekind_capName (e->ukind),
6117 uentry_getName (e)),
6118 f))
6119 {
6120 llgenindentmsg (message ("Previous definition of %q",
6121 uentry_getName (e)),
6122 e->whereDefined);
6123 }
6124 }
6125 }
6126 }
6127 else
6128 {
6129 e->whereDefined = fileloc_update (e->whereDefined, f);
6130 }
6131}
6132
6133bool
6134uentry_isCodeDefined (uentry e)
6135{
efd360a3 6136 llassert (uentry_isValid (e));
6137
6138 return (fileloc_isDefined (e->whereDefined));
616915dd 6139}
6140
6141bool
6142uentry_isDeclared (uentry e)
6143{
6144 if (uentry_isValid (e))
6145 {
6146 return (fileloc_isDefined (e->whereDeclared));
6147 }
6148
6149 return FALSE;
6150}
6151
6152sRef uentry_getSref (uentry e)
6153{
6154 /* not true, used for functions too (but shouldn't be? */
6155 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6156
6157 if (uentry_isInvalid (e)) return sRef_undefined;
6158
6159 return (e->sref);
6160}
6161
6162sRef uentry_getOrigSref (uentry e)
6163{
68de3f33 6164 /*@i523*/ /* evans 2001-09-09 - need to fix this
b7e84605 6165 if (uentry_isValid (e))
6166 {
6167 if (uentry_isVariable (e))
6168 {
6169 return e->info->var->origsref;
6170 }
6171 else
6172 {
6173 sRef sr = sRef_copy (uentry_getSref (e));
6174
6175 sRef_resetState (sr);
6176 sRef_clearDerived (sr);
6177 return (sr);
6178 }
6179 }
6180 else
6181 {
6182 return sRef_undefined;
6183 }
6184 */
6185
616915dd 6186 if (uentry_isValid (e))
6187 {
6188 sRef sr = sRef_copy (uentry_getSref (e));
6189
6190 sRef_resetState (sr);
6191 sRef_clearDerived (sr);
6192
6193 if (uentry_isVariable (e))
6194 {
6195 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6196 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6197 }
6198
6199 return (sr);
6200 }
6201 else
6202 {
6203 return sRef_undefined;
6204 }
6205}
6206
6207/*
6208** requires: uentry e is not in a hashed symbol table
6209*/
6210
6211void
6212uentry_setName (uentry e, /*@only@*/ cstring n)
6213{
6214 llassert (uentry_isValid (e));
6215
6216 cstring_free (e->uname);
6217 e->uname = n;
6218}
6219
6220void
6221uentry_setType (uentry e, ctype t)
6222{
6223 if (uentry_isValid (e))
6224 {
6225 e->utype = t;
6226 sRef_setType (e->sref, t);
6227 }
6228}
6229
6230void
6231uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6232{
6233 ctype rct;
6234 ctype rettype = ctype_unknown;
6235
6236 llassert (uentry_isValid (ue));
6237
efd360a3 6238 uentry_convertVarFunction (ue);
616915dd 6239 llassert (uentry_isFunction (ue));
6240
efd360a3 6241 rct = ctype_realType (ue->utype);
6242
616915dd 6243 if (ctype_isFunction (rct))
6244 {
28bf4b0b 6245 rettype = ctype_getReturnType (rct);
616915dd 6246 }
6247
6248 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6249}
6250
6251void
6252uentry_setRefParam (uentry e)
6253{
616915dd 6254 if (!uentry_isVar (e))
6255 {
6256 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6257 }
6258 else
6259 {
6260 if (e->info->var->kind == VKSEFPARAM)
6261 {
6262 e->info->var->kind = VKREFSEFPARAM;
6263 }
6264 else if (e->info->var->kind == VKSEFRETPARAM)
6265 {
6266 e->info->var->kind = VKREFSEFRETPARAM;
6267 }
6268 else if (e->info->var->kind == VKYIELDPARAM)
6269 {
6270 e->info->var->kind = VKREFYIELDPARAM;
6271 }
6272 else
6273 {
6274 e->info->var->kind = VKREFPARAM;
6275 }
6276 }
6277}
6278
6279void
6280uentry_setParam (uentry e)
6281{
6282 if (!uentry_isVar (e))
6283 {
6284 if (uentry_isElipsisMarker (e))
6285 {
6286
6287 }
6288 else
6289 {
6290 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6291 }
6292 }
6293 else
6294 {
6295 cstring oldname;
6296
6297 if (e->info->var->kind == VKYIELDPARAM
6298 || e->info->var->kind == VKSEFPARAM
6299 || e->info->var->kind == VKSEFRETPARAM)
6300 {
6301 ;
6302 }
6303 else
6304 {
6305 e->info->var->kind = VKPARAM;
6306 }
6307
6308 oldname = e->uname;
6309 e->uname = makeParam (e->uname);
6310 cstring_free (oldname);
6311 }
6312}
6313
6314void
6315uentry_setSref (uentry e, sRef s)
6316{
6317 if (uentry_isValid (e))
6318 {
6319 if (sRef_isValid (e->sref))
6320 {
6321 sRef_mergeStateQuietReverse (e->sref, s);
6322 }
6323 else
6324 {
6325 e->sref = sRef_saveCopy (s);
6326 }
6327 }
6328}
6329
6330ctype
6331uentry_getAbstractType (uentry e)
6332{
6333 llassert (uentry_isDatatype (e));
6334
6335 /*
6336 ** This assertion removed.
6337 ** Okay to have undefined type, for system types
6338
6339 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6340 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6341 e->utype);
6342
6343 */
6344
6345 if (ctype_isUndefined (e->info->datatype->type))
6346 {
6347 return ctype_unknown;
6348 }
6349
6350 /*
6351 ** Sadly, a kludge...
6352 */
6353
6354 if (ctype_isUserBool (e->info->datatype->type)) {
6355 return ctype_bool;
6356 }
6357
6358 return e->info->datatype->type;
6359}
6360
6361ctype uentry_getRealType (uentry e)
6362{
6363 ctype ct;
6364 typeId uid = USYMIDINVALID;
6365
6366 if (uentry_isInvalid (e))
6367 {
6368 return ctype_unknown;
6369 }
6370
6371 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6372
6373 if (uentry_isAnyTag (e))
6374 {
6375 return (e->utype);
6376 }
6377
6378 if (uentry_isAbstractType (e))
6379 {
6380 ct = uentry_getAbstractType (e);
6381
6382 if (ctype_isManifestBool (ct)) {
6383 return ct;
6384 }
6385
6386 llassert (ctype_isUA (ct));
6387
6388 uid = ctype_typeId (ct);
6389
6390 if (!context_hasAccess (uid))
6391 {
6392 return (ct);
6393 }
6394 }
6395
6396 ct = uentry_getType (e);
6397
6398 /* if (ctype_isUserBool (ct)) return ct; */
6399
6400 if (ctype_isManifestBool (ct)) {
6401 return ctype_bool;
6402 }
6403
6404 if (ctype_isUA (ct))
6405 {
6406 usymId iid = ctype_typeId (ct);
6407
28bf4b0b 6408 if (usymId_equal (iid, uid))
616915dd 6409 {
6410 llcontbug (message ("uentry_getRealType: recursive type! %s",
6411 ctype_unparse (ct)));
6412 return ct;
6413 }
6414 else
6415 {
6416 /* evs 2000-07-25: possible infinite recursion ? */
6417 uentry ue2 = usymtab_getTypeEntry (iid);
28bf4b0b 6418
6419 if (ue2 == e)
6420 {
6421 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6422 return ctype_unknown;
6423 }
616915dd 6424
6425 return uentry_getRealType (ue2);
6426 }
6427 }
6428 else
6429 {
6430 return ct;
6431 }
6432}
6433
6434ctype uentry_getForceRealType (uentry e)
6435{
6436 ctype ct;
6437 typeId uid = USYMIDINVALID;
6438
6439 if (uentry_isInvalid (e))
6440 {
6441 return ctype_unknown;
6442 }
6443
6444 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6445
6446 if (uentry_isAnyTag (e))
6447 {
6448 return (e->utype);
6449 }
6450
6451 if (uentry_isAbstractType (e))
6452 {
6453 ct = uentry_getAbstractType (e);
6454 llassert (ctype_isUA (ct));
6455
6456 uid = ctype_typeId (ct);
6457 /* no check for access! */
6458 }
6459
6460 ct = uentry_getType (e);
6461
6462 /* evs 2000-07-25 */
6463 /* if (ctype_isUserBool (ct)) return ct; */
6464
6465 if (ctype_isManifestBool (ct)) {
6466 return ctype_bool;
6467 }
6468
6469 if (ctype_isUA (ct))
6470 {
6471 usymId iid = ctype_typeId (ct);
6472
28bf4b0b 6473 if (usymId_equal (iid, uid))
616915dd 6474 {
6475 llcontbug (message ("uentry_getRealType: recursive type! %s",
6476 ctype_unparse (ct)));
6477 return ct;
6478 }
6479 else
6480 {
6481 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6482 }
6483 }
6484 else
6485 {
6486 return ct;
6487 }
6488}
6489
6490uentry uentry_nameCopy (cstring name, uentry e)
6491{
6492 uentry enew = uentry_alloc ();
6493
6494 llassert (uentry_isValid (e));
6495
6496 /* enew->shallowCopy = FALSE; */
6497 enew->ukind = e->ukind;
6498 enew->uname = name;
6499 enew->utype = e->utype;
6500 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6501 enew->whereDefined = fileloc_copy (e->whereDefined);
6502 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6503 enew->sref = sRef_copy (e->sref);
6504 enew->used = e->used;
6505 enew->lset = FALSE;
6506 enew->isPrivate = e->isPrivate;
6507 enew->hasNameError = FALSE;
6508
6509 enew->uses = filelocList_new ();
28bf4b0b 6510 enew->warn = warnClause_undefined;
616915dd 6511
6512 enew->storageclass = e->storageclass;
6513 enew->info = uinfo_copy (e->info, e->ukind);
6514
6515 return enew;
6516}
6517
6518void
6519uentry_setDatatype (uentry e, usymId uid)
6520{
6521 llassert (uentry_isDatatype (e));
6522
6523 if (uentry_isAbstractType (e))
6524 {
6525 e->info->datatype->type = ctype_createAbstract (uid);
6526 }
6527 else
6528 {
6529 e->info->datatype->type = ctype_createUser (uid);
6530 }
6531}
6532
6533static void
6534uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6535 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6536 /*@modifies e@*/
6537{
6538 llassert (uentry_isValid (e));
6539
6540 if (fileloc_isSpec (f) || fileloc_isImport (f))
6541 {
6542 e->whereSpecified = f;
6543 e->whereDeclared = fileloc_undefined;
6544 e->whereDefined = fileloc_undefined;
6545 }
6546 else
6547 {
6548 e->whereSpecified = fileloc_undefined;
6549 e->whereDeclared = f;
6550 e->whereDefined = fileloc_undefined;
6551 }
7ebcc5bb 6552
6553 llassert (fileloc_storable (f));
616915dd 6554}
6555
6556static void
6557ucinfo_free (/*@only@*/ ucinfo u)
6558{
616915dd 6559 sfree (u);
6560}
6561
6562static void
6563uvinfo_free (/*@only@*/ uvinfo u)
6564{
28bf4b0b 6565 /*drl7x added 6/29/01 */
b072092f 6566 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
616915dd 6567 sfree (u);
6568}
6569
6570static void
6571udinfo_free (/*@only@*/ udinfo u)
6572{
6573 sfree (u);
6574}
6575
6576static void
6577ufinfo_free (/*@only@*/ ufinfo u)
6578{
6579 globSet_free (u->globs);
6580 sRefSet_free (u->mods);
28bf4b0b 6581 stateClauseList_free (u->specclauses);
616915dd 6582 sfree (u);
6583}
6584
6585static void
6586uiinfo_free (/*@only@*/ uiinfo u)
6587{
6588 sfree (u);
6589}
6590
6591static void
6592ueinfo_free (/*@only@*/ ueinfo u)
6593{
6594 sfree (u);
6595}
6596
6597static /*@only@*/ ucinfo
6598ucinfo_copy (ucinfo u)
6599{
6600 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
616915dd 6601 ret->access = u->access;
616915dd 6602 return ret;
6603}
6604
6605static /*@only@*/ uvinfo
6606uvinfo_copy (uvinfo u)
6607{
6608 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6609
6610 ret->kind = u->kind;
6611 ret->nullstate = u->nullstate;
6612 ret->defstate = u->defstate;
6613 ret->checked = u->checked;
28bf4b0b 6614
b7e84605 6615 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6616
28bf4b0b 6617 /* drl added 07-02-001 */
6618 /* copy null terminated information */
6619
6620 if (u->bufinfo != NULL)
6621 {
6622 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6623 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6624 ret->bufinfo->size = u->bufinfo->size;
6625 ret->bufinfo->len = u->bufinfo->len;
6626 return ret;
6627 }
6628 else
6629 {
6630 ret->bufinfo = NULL;
6631 return ret;
6632 }
6633
616915dd 6634}
6635
6636static /*@only@*/ udinfo
6637udinfo_copy (udinfo u)
6638{
6639 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6640
6641 ret->abs = u->abs;
6642 ret->mut = u->mut;
6643 ret->type = u->type;
6644
6645 return ret;
6646}
6647
6648static /*@only@*/ ufinfo
6649ufinfo_copy (ufinfo u)
6650{
6651 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6652
6653 ret->hasGlobs = u->hasGlobs;
6654 ret->hasMods = u->hasMods;
6655 ret->exitCode = u->exitCode;
6656 ret->specialCode = u->specialCode;
6657 ret->nullPred = u->nullPred;
6658 ret->access = u->access;
6659 ret->globs = globSet_newCopy (u->globs);
6660 ret->mods = sRefSet_newCopy (u->mods);
6661 ret->defparams = u->defparams;
28bf4b0b 6662 ret->specclauses = stateClauseList_copy (u->specclauses);
616915dd 6663
3814599d 6664 ret->preconditions = functionConstraint_copy (u->preconditions);
6665 ret->postconditions = functionConstraint_copy (u->postconditions);
616915dd 6666
6667 return ret;
6668}
6669
6670static /*@only@*/ uiinfo
6671uiinfo_copy (uiinfo u)
6672{
6673 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6674
6675 ret->access = u->access;
6676 ret->globs = globSet_newCopy (u->globs);
6677 ret->mods = sRefSet_newCopy (u->mods);
6678
6679 return (ret);
6680}
6681
6682static /*@only@*/ ueinfo
6683ueinfo_copy (ueinfo u)
6684{
6685 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6686
6687 ret->access = u->access;
6688 return ret;
6689}
6690
6691static void
6692uinfo_free (uinfo u, ekind kind)
6693{
6694 switch (kind)
6695 {
6696 case KENUMCONST:
6697 case KCONST: ucinfo_free (u->uconst); break;
6698 case KVAR: uvinfo_free (u->var); break;
6699 case KSTRUCTTAG:
6700 case KUNIONTAG:
6701 case KENUMTAG:
6702 case KDATATYPE: udinfo_free (u->datatype); break;
6703 case KFCN: ufinfo_free (u->fcn); break;
6704 case KITER: uiinfo_free (u->iter); break;
6705 case KENDITER: ueinfo_free (u->enditer); break;
6706 case KELIPSMARKER: break;
6707 case KINVALID: break;
6708 }
6709
6710 sfree (u);
6711}
6712
6713static /*@only@*/ /*@null@*/ uinfo
6714uinfo_copy (uinfo u, ekind kind)
6715{
6716 if (kind == KELIPSMARKER || kind == KINVALID)
6717 {
6718 return NULL;
6719 }
6720 else
6721 {
6722 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6723
6724 switch (kind)
6725 {
6726 case KENUMCONST:
6727 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6728 case KVAR: ret->var = uvinfo_copy (u->var); break;
6729 case KSTRUCTTAG:
6730 case KUNIONTAG:
6731 case KENUMTAG:
6732 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6733 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6734 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6735 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6736 BADDEFAULT;
6737 }
6738 return ret;
6739 }
6740}
6741
6742static void
6743uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6744{
6745 filelocList_free (e->uses);
6746 cstring_free (e->uname);
6747
6748 uinfo_free (e->info, e->ukind);
6749
6750 fileloc_free (e->whereSpecified);
6751 fileloc_free (e->whereDefined);
6752 fileloc_free (e->whereDeclared);
6753
28bf4b0b 6754 warnClause_free (e->warn);
6755
616915dd 6756 nuentries--;
6757 sfree (e);
6758 }
6759
6760extern void uentry_markOwned (/*@owned@*/ uentry u)
6761{
6762 sfreeEventually (u);
6763}
6764
6765void
6766uentry_free (/*@only@*/ uentry e)
6767{
6768 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6769 {
6770 uentry_reallyFree (e);
6771 }
6772}
6773
6774/*
6775** For uentry's in the global or file scope
6776*/
6777
6778void
6779uentry_freeComplete (/*@only@*/ uentry e)
6780{
6781 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6782 {
28bf4b0b 6783 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
616915dd 6784 /*@i@*/ sRef_free (e->sref);
6785 e->sref = sRef_undefined;
6786 uentry_reallyFree (e);
6787 }
6788}
6789
6790/*
6791** requires old->kind != new->kind, old->uname = new->uname
6792*/
6793
6794static void
6795KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6796{
6797 llassert (uentry_isValid (old));
6798 llassert (uentry_isValid (unew));
6799
6800 if (uentry_isEitherConstant (unew)
6801 && (fileloc_isPreproc (uentry_whereDeclared (old))
6802 || ctype_isUnknown (old->utype))
6803 && !uentry_isSpecified (old))
6804 {
6805 ; /* no error */
6806 }
6807 else
6808 {
6809 if (mustConform)
6810 {
6811 if (!uentry_isDeclared (old))
6812 {
6813 if (uentry_isSpecified (old))
6814 {
6815 if (uentry_isSpecified (unew))
6816 {
6817 llbuglit ("Respecification!");
6818 }
6819 else if (uentry_isDeclared (unew))
6820 {
6821 if (optgenerror
6822 (FLG_INCONDEFS,
6823 message ("%s %q inconsistently declared as %s: %t",
6824 ekind_capName (old->ukind),
6825 uentry_getName (unew),
6826 ekind_unparseLong (unew->ukind),
6827 unew->utype),
f2b6724f 6828 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6829 {
f2b6724f 6830 uentry_showWhereLastKind (old);
616915dd 6831 }
6832 }
6833 else
6834 {
6835 BADEXIT;
6836 }
6837 }
6838 else
6839 {
6840 if (optgenerror
6841 (FLG_INCONDEFS,
6842 message ("%s %q inconsistently declared as %s: %t",
6843 ekind_capName (old->ukind),
6844 uentry_getName (unew),
6845 ekind_unparseLong (unew->ukind),
6846 unew->utype),
f2b6724f 6847 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6848 {
f2b6724f 6849 uentry_showWhereLastKind (old);
616915dd 6850 }
6851 }
6852 }
6853 else
6854 {
6855 llassert (uentry_isDeclared (unew));
6856
f2b6724f 6857 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6858 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6859
616915dd 6860 if (optgenerror
6861 (FLG_INCONDEFS,
6862 message ("%s %q inconsistently redeclared as %s",
6863 ekind_capName (old->ukind),
6864 uentry_getName (unew),
6865 ekind_unparseLong (unew->ukind)),
f2b6724f 6866 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6867 {
f2b6724f 6868 uentry_showWhereLastKind (old);
616915dd 6869 }
6870 }
6871 }
6872 }
6873
efd360a3 6874 uentry_updateInto (old, unew);
616915dd 6875}
6876
6877/*
6878** def is the definition of spec, modifies spec
6879**
6880** reports any inconsistencies
6881** returns the summary of all available information
6882** if spec and def are inconsistent, def is returned
6883*/
6884
6885void
6886uentry_showWhereLast (uentry spec)
6887{
6888 if (uentry_isValid (spec))
6889 {
6890 if (fileloc_isDefined (spec->whereDefined)
6891 && !fileloc_isLib (spec->whereDefined)
f2b6724f 6892 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
616915dd 6893 {
6894 llgenindentmsg (message ("Previous definition of %q: %t",
6895 uentry_getName (spec),
6896 uentry_getType (spec)),
6897 uentry_whereDefined (spec));
6898 }
6899 else if (uentry_isDeclared (spec))
6900 {
6901 llgenindentmsg (message ("Previous declaration of %q: %t",
6902 uentry_getName (spec),
6903 uentry_getType (spec)),
6904 uentry_whereDeclared (spec));
6905 }
6906 else if (uentry_isSpecified (spec))
6907 {
6908 if (uentry_hasName (spec))
6909 {
6910 llgenindentmsg (message ("Specification of %q: %t",
6911 uentry_getName (spec),
6912 uentry_getType (spec)),
6913 uentry_whereSpecified (spec));
6914 }
6915 else
6916 {
6917 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6918 uentry_whereSpecified (spec));
6919 }
6920 }
6921 else
6922 {
6923 /* nothing to show */
6924 }
6925 }
6926}
6927
f2b6724f 6928static void
6929uentry_showWhereLastKind (uentry spec)
6930{
6931 if (uentry_isValid (spec))
6932 {
6933 if (fileloc_isDefined (spec->whereDefined)
6934 && !fileloc_isLib (spec->whereDefined)
6935 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6936 {
6937 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6938 uentry_getName (spec),
6939 ekind_unparseLong (spec->ukind),
6940 uentry_getType (spec)),
6941 uentry_whereDefined (spec));
6942 }
6943 else if (uentry_isDeclared (spec))
6944 {
6945 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6946 uentry_getName (spec),
6947 ekind_unparseLong (spec->ukind),
6948 uentry_getType (spec)),
6949 uentry_whereDeclared (spec));
6950 }
6951 else if (uentry_isSpecified (spec))
6952 {
6953 if (uentry_hasName (spec))
6954 {
6955 llgenindentmsg (message ("Specification of %q as %s: %t",
6956 uentry_getName (spec),
6957 ekind_unparseLong (spec->ukind),
6958 uentry_getType (spec)),
6959 uentry_whereSpecified (spec));
6960 }
6961 else
6962 {
6963 llgenindentmsg (message ("Specification as %s: %t",
6964 ekind_unparseLong (spec->ukind),
6965 uentry_getType (spec)),
6966 uentry_whereSpecified (spec));
6967 }
6968 }
6969 else
6970 {
6971 /* nothing to show */
6972 }
6973 }
6974}
6975
616915dd 6976void
6977uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6978{
6979 fileloc loc = uentry_whereDefined (ce);
6980
6981 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6982 {
6983 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6984 loc);
6985 }
6986
6987 loc = uentry_whereSpecified (ce);
6988
6989 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6990 {
6991 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6992 loc);
6993 }
6994}
6995
6996void uentry_showWhereLastExtra (uentry spec, cstring extra)
6997{
6998 if (uentry_isDeclared (spec))
6999 {
7000 llgenindentmsg (message ("Previous declaration of %q: %q",
7001 uentry_getName (spec), extra),
7002 uentry_whereDeclared (spec));
7003 }
7004 else if (uentry_isSpecified (spec))
7005 {
7006 llgenindentmsg (message ("Specification of %q: %q",
7007 uentry_getName (spec), extra),
7008 uentry_whereSpecified (spec));
7009 }
7010 else
7011 {
7012 cstring_free (extra);
7013 }
7014}
7015
7016void
7017uentry_showWhereDeclared (uentry spec)
7018{
7019 if (uentry_isDeclared (spec))
7020 {
7021 if (uentry_hasName (spec))
7022 {
7023 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7024 uentry_whereDeclared (spec));
7025 }
7026 else
7027 {
7028 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7029 }
7030 }
7031 else if (uentry_isSpecified (spec))
7032 {
7033 if (uentry_hasName (spec))
7034 {
7035 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7036 uentry_whereSpecified (spec));
7037 }
7038 else
7039 {
7040 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7041 }
7042 }
7043 else
7044 {
7045 /* nothing to show */
7046 }
7047
7048}
7049
7050void
7051uentry_showWhereAny (uentry spec)
7052{
7053 if (uentry_isDeclared (spec))
7054 {
7055 if (uentry_hasName (spec))
7056 {
7057 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7058 uentry_whereDeclared (spec));
7059 }
7060 else
7061 {
7062 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7063 }
7064 }
7065 else if (uentry_isSpecified (spec))
7066 {
7067 if (uentry_hasName (spec))
7068 {
7069 llgenindentmsg (message ("Specification of %q",
7070 uentry_getName (spec)),
7071 uentry_whereSpecified (spec));
7072 }
7073 else
7074 {
7075 llgenindentmsg (cstring_makeLiteral ("Specification"),
7076 uentry_whereSpecified (spec));
7077 }
7078 }
7079 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7080 {
7081 if (uentry_hasName (spec))
7082 {
7083 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7084 uentry_whereDefined (spec));
7085 }
7086 else
7087 {
7088 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7089 }
7090 }
7091 else
7092 {
7093 /* nothing to show */
7094 }
7095}
7096
7097void
7098uentry_showWhereDefined (uentry spec)
7099{
7100 if (uentry_isCodeDefined (spec))
7101 {
7102 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7103 uentry_whereDefined (spec));
7104 }
7105}
7106
7107void
7108uentry_showWhereLastPlain (uentry spec)
7109{
7110 if (uentry_isDeclared (spec))
7111 {
7112 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7113 uentry_whereDeclared (spec));
7114 }
7115 else if (uentry_isSpecified (spec))
7116 {
7117 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7118 uentry_whereSpecified (spec));
7119 }
7120 else
7121 {
7122 }
7123}
7124
7125static void
7126uentry_showWhereLastVal (uentry spec, cstring val)
7127{
7128 if (uentry_isDeclared (spec))
7129 {
7130 llgenindentmsg (message ("Previous declaration of %q: %s",
7131 uentry_getName (spec), val),
7132 uentry_whereDeclared (spec));
7133 }
7134 else if (uentry_isSpecified (spec))
7135 {
7136 llgenindentmsg (message ("Specification of %q: %s",
7137 uentry_getName (spec), val),
7138 uentry_whereSpecified (spec));
7139 }
7140 else
7141 {
7142 }
7143}
7144
7145void
7146uentry_showWhereSpecified (uentry spec)
7147{
7148 if (uentry_isSpecified (spec))
7149 {
7150 if (uentry_hasName (spec))
7151 {
7152 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7153 uentry_whereSpecified (spec));
7154 }
7155 else
7156 {
7157 llgenindentmsg (cstring_makeLiteral ("Specification"),
7158 uentry_whereSpecified (spec));
7159 }
7160 }
7161 else if (uentry_isDeclared (spec))
7162 {
7163 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7164 uentry_whereDeclared (spec));
7165 }
7166 else
7167 {
7168 /* nothing to show */
7169 }
7170}
7171
7172void
7173uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7174{
7175 if (uentry_isSpecified (spec))
7176 {
7177 if (uentry_hasName (spec))
7178 {
7179 llgenindentmsg (message ("Specification of %q: %q",
7180 uentry_getName (spec), s),
7181 uentry_whereSpecified (spec));
7182 }
7183 else
7184 {
7185 llgenindentmsg (message ("Specification: %q", s),
7186 uentry_whereSpecified (spec));
7187 }
7188 }
7189 else if (uentry_isDeclared (spec))
7190 {
7191 llgenindentmsg (message ("Declaration of %q: %q",
7192 uentry_getName (spec), s),
7193 uentry_whereDeclared (spec));
7194 }
7195 else
7196 {
7197 llgenindentmsg (message ("Previous: %q", s),
7198 uentry_whereLast (spec));
7199 }
7200}
7201
7202/*
7203**
7204*/
7205
7206static void
7207checkStructConformance (uentry old, uentry unew)
7208{
7209 ctype oldr, newr;
7210 uentryList fold, fnew;
7211
7212 /*
7213 ** requires: types of old and new are structs or unions
7214 */
7215
7216 llassert (uentry_isValid (old));
7217 llassert (uentry_isValid (unew));
7218
7219 oldr = ctype_realType (old->utype);
7220 fold = ctype_getFields (oldr);
7221
7222 newr = ctype_realType (unew->utype);
7223 fnew = ctype_getFields (newr);
7224
7225 if (!uentryList_matchFields (fold, fnew))
7226 {
7227 if (fileloc_equal (uentry_whereLast (old),
7228 uentry_whereLast (unew)))
7229 {
7230 ; /* cheat! */
7231 }
7232 else
7233 {
7234 if (optgenerror
7235 (FLG_MATCHFIELDS,
7236 message ("%q %q %rdeclared with fields { %q }, %s "
7237 "with fields { %q }",
7238 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7239 uentry_getName (old),
7240 uentry_isDeclared (old),
7241 uentryList_unparseAbbrev (fnew),
7242 uentry_specOrDefName (old),
7243 uentryList_unparseAbbrev (fold)),
7244 uentry_whereDeclared (unew)))
7245 {
7246 uentry_showWhereLastPlain (old);
7247 uentryList_showFieldDifference (fold, fnew);
7248 }
7249 }
7250
7251 old->utype = unew->utype;
7252 }
7253}
7254
7255static void
7256checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7257{
7258 /*
7259 ** requires old and new are enums
7260 */
7261
7262 ctype rold = ctype_realType (old->utype);
7263 ctype rnew = ctype_realType (unew->utype);
7264 enumNameList eold = ctype_elist (rold);
7265 enumNameList enew = ctype_elist (rnew);
7266
7267 if (!enumNameList_match (eold, enew))
7268 {
7269 if (optgenerror
7270 (FLG_MATCHFIELDS,
7271 message ("Enum %q declared with members { %q } but "
7272 "specified with members { %q }",
7273 uentry_getName (old),
7274 enumNameList_unparse (enew),
7275 enumNameList_unparse (eold)),
7276 uentry_whereDeclared (unew)))
7277 {
7278 uentry_showWhereSpecified (old);
7279 old->utype = unew->utype;
7280 }
7281 }
7282}
7283
7284/*
7285** either oldCurrent or newCurrent may be undefined!
7286*/
7287
7288static void
7289paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7290 uentry unew, uentry newCurrent, ctype newType,
7291 int paramno)
7292{
7293 bool hasError = FALSE;
7294
7295 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7296 {
7297 if (uentry_hasName (newCurrent))
7298 {
7299 hasError = optgenerror
7300 (FLG_TYPE,
7301 message ("Parameter %d, %q, of function %q has inconsistent type: "
7302 "declared %t, %s %t",
7303 paramno + 1, uentry_getName (newCurrent),
7304 uentry_getName (unew),
7305 newType, uentry_specOrDefName (old), oldType),
7306 uentry_whereDeclared (newCurrent));
7307 }
7308 else
7309 {
7310 hasError = optgenerror
7311 (FLG_TYPE,
7312 message ("Parameter %d of function %q has inconsistent type: "
7313 "declared %t, %s %t",
7314 paramno + 1, uentry_getName (unew),
7315 newType, uentry_specOrDefName (old), oldType),
7316 uentry_whereDeclared (newCurrent));
7317
7318 DPRINTF (("type: %s / %s",
7319 ctype_unparse (newType),
7320 ctype_unparse (ctype_realType (newType))));
7321 }
7322 }
7323 else
7324 {
7325 if (uentry_isDeclared (unew))
7326 {
7327 hasError = optgenerror
7328 (FLG_TYPE,
7329 message ("Parameter %d of function %s has inconsistent type: "
7330 "declared %t, %s %t",
7331 paramno + 1, unew->uname,
7332 newType, uentry_specOrDefName (old), oldType),
7333 uentry_whereDeclared (unew));
7334 }
7335 else
7336 {
7337 hasError = optgenerror
7338 (FLG_TYPE,
7339 message ("Parameter %d of function %s has inconsistent type: "
7340 "declared %t, %s %t",
7341 paramno + 1, unew->uname,
7342 newType, uentry_specOrDefName (old), oldType),
7343 uentry_whereDeclared (unew));
7344 }
7345 }
7346
7347 if (hasError)
7348 {
6970c11b 7349 DPRINTF (("Here: %s / %s",
7350 uentry_unparseFull (oldCurrent),
7351 uentry_unparseFull (newCurrent)));
7352
616915dd 7353 if (!uentry_isUndefined (oldCurrent))
7354 {
7355 if (!uentry_isUndefined (newCurrent)
7356 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7357 {
7358 uentry_showWhereLast (oldCurrent);
7359 }
7360 else
7361 {
7362 uentry_showWhereLastPlain (old);
7363 }
7364
7365 uentry_setType (oldCurrent, newType);
7366 }
7367 else
7368 {
7369 uentry_showWhereLastPlain (old);
7370 }
7371 }
7372}
7373
7374static void
7375nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7376{
7377 if (optgenerror
7378 (FLG_TYPE,
28bf4b0b 7379 message ("Function %s %rdeclared with %d arg%&, %s with %d",
616915dd 7380 unew->uname,
7381 uentry_isDeclared (old),
7382 uentryList_size (uentry_getParams (unew)),
7383 uentry_specOrDefName (old),
7384 uentryList_size (uentry_getParams (old))),
7385 uentry_whereDeclared (unew)))
7386 {
7387 uentry_showWhereLastPlain (old);
7388 }
7389}
7390
7391static void
7392returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7393{
7394 if (optgenerror
7395 (FLG_INCONDEFS,
7396 message ("Function %s inconsistently %rdeclared to return %t",
7397 unew->uname,
7398 uentry_isDeclared (old),
28bf4b0b 7399 ctype_getReturnType (unew->utype)),
616915dd 7400 uentry_whereDeclared (unew)))
7401 {
28bf4b0b 7402 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
616915dd 7403 }
7404}
7405
7406static cstring paramStorageName (uentry ue)
7407{
7408 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7409}
7410
7411static cstring fcnErrName (uentry ue)
7412{
7413 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7414}
7415
7416extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7417{
7418 if (uentry_isVar (ue))
7419 {
7420 return (checkedName (ue->info->var->checked));
7421 }
7422 else
7423 {
7424 return (cstring_makeLiteralTemp ("<checked invalid>"));
7425 }
7426}
7427
7428static cstring checkedName (chkind checked)
7429{
7430 switch (checked)
7431 {
7432 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7433 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7434 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7435 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7436 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7437 }
7438 BADEXIT;
7439}
7440
7441static
7442void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7443{
7444 nstate oldState;
7445 nstate newState;
7446
7447 if (uentry_isVar (unew))
7448 {
7449 llassert (uentry_isVar (old));
7450
7451 oldState = old->info->var->nullstate;
7452 newState = unew->info->var->nullstate;
7453 }
7454 else
7455 {
7456 oldState = sRef_getNullState (old->sref);
7457 newState = sRef_getNullState (unew->sref);
7458 }
7459
7460 if (oldState == NS_ABSNULL)
7461 {
7462 if (uentry_isVar (old))
7463 {
7464 old->info->var->nullstate = newState;
7465 }
7466
7467 sRef_mergeNullState (old->sref, newState);
7468 }
7469 else if (newState == NS_UNKNOWN)
7470 {
7471 if (completeConform && newState != oldState
7472 && uentry_isReallySpecified (old))
7473 {
7474 if (optgenerror
7475 (FLG_NEEDSPEC,
7476 message ("%s %q specified as %s, but declared without %s qualifier",
7477 ekind_capName (unew->ukind),
7478 uentry_getName (unew),
7479 nstate_unparse (oldState),
7480 nstate_unparse (oldState)),
7481 uentry_whereDeclared (unew)))
7482 {
7483 uentry_showWhereSpecified (old);
7484 }
7485 }
7486
7487 if (uentry_isVar (unew))
7488 {
7489 unew->info->var->nullstate = oldState;
7490 }
7491
7492 sRef_mergeNullState (unew->sref, oldState);
7493 }
7494 else if (newState == NS_POSNULL)
7495 {
7496 if (oldState == NS_MNOTNULL
7497 && (ctype_isUA (unew->utype)
7498 || (uentry_isFunction (unew)
28bf4b0b 7499 && ctype_isUA (ctype_getReturnType (unew->utype)))))
616915dd 7500 {
7501 if (uentry_isVar (unew))
7502 {
7503 unew->info->var->nullstate = oldState;
7504 }
7505
7506 sRef_mergeNullState (unew->sref, oldState);
7507 }
7508 else
7509 {
7510 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7511 || oldState == NS_UNKNOWN)
7512 {
7513 if (mustConform)
7514 {
7515 if (optgenerror
7516 (FLG_INCONDEFS,
7517 message
7518 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7519 "%s %q qualifier",
7520 uentry_ekindName (unew),
7521 uentry_getName (unew),
7522 uentry_isDeclared (old),
7523 fcnErrName (unew),
7524 uentry_specOrDefName (old),
7525 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7526 uentry_whereDeclared (unew)))
7527 {
7528 uentry_showWhereSpecified (old);
7529 }
7530 }
7531 }
7532
7533 if (uentry_isVar (old))
7534 {
7535 old->info->var->nullstate = newState;
7536 }
7537
7538 sRef_mergeNullState (old->sref, newState);
7539 }
7540 }
7541 else if (newState == NS_MNOTNULL)
7542 {
7543 if (oldState != NS_MNOTNULL)
7544 {
7545 if (mustConform)
7546 {
7547 if (optgenerror
7548 (FLG_INCONDEFS,
7549 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7550 "%s without notnull qualifier",
7551 uentry_ekindName (unew),
7552 uentry_getName (unew),
7553 uentry_isDeclared (old),
7554 fcnErrName (unew),
7555 uentry_specOrDefName (old)),
7556 uentry_whereDeclared (unew)))
7557 {
7558 uentry_showWhereSpecified (old);
7559 }
7560 }
7561
7562 if (uentry_isVar (old))
7563 {
7564 old->info->var->nullstate = newState;
7565 }
7566
7567 sRef_mergeNullState (old->sref, newState);
7568 }
7569 }
7570 else
7571 {
7572 if (uentry_isVar (unew))
7573 {
7574 unew->info->var->nullstate = oldState;
7575 }
7576
7577 sRef_mergeNullState (unew->sref, oldState);
7578 }
7579}
7580
7581static
7582void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7583 bool mustConform, bool completeConform)
7584{
7585 sstate oldState;
7586 sstate newState;
7587 bool vars = FALSE;
7588
7589 if (uentry_isVar (old) && uentry_isVar (unew))
7590 {
7591 oldState = old->info->var->defstate;
7592 newState = unew->info->var->defstate;
7593 vars = TRUE;
7594 }
7595 else
7596 {
7597 oldState = sRef_getDefState (old->sref);
7598 newState = sRef_getDefState (unew->sref);
7599 }
7600
28bf4b0b 7601 if (newState != oldState
7602 && newState != SS_UNKNOWN
7603 && newState != SS_DEFINED)
616915dd 7604 {
7605 if (mustConform)
7606 {
7607 if (optgenerror
7608 (FLG_INCONDEFS,
7609 message ("%s %q inconsistently %rdeclared %s %s %s, "
7610 "%s %s %s %s",
7611 uentry_ekindName (unew),
7612 uentry_getName (unew),
7613 uentry_isDeclared (old),
7614 fcnErrName (unew),
7615 sstate_unparse (newState),
7616 paramStorageName (unew),
7617 uentry_specOrDefName (old),
7618 fcnErrName (unew),
7619 sstate_unparse (oldState),
7620 paramStorageName (unew)),
7621 uentry_whereDeclared (unew)))
7622 {
7623 uentry_showWhereSpecified (old);
7624 }
7625 }
28bf4b0b 7626
616915dd 7627 if (vars) old->info->var->defstate = newState;
7628 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7629 }
7630 else
7631 {
7632 if (completeConform
7633 && (newState != oldState) && (oldState != SS_DEFINED)
7634 && uentry_isReallySpecified (old))
7635 {
7636 if (optgenerror
7637 (FLG_NEEDSPEC,
7638 message ("%s %q specified as %s, but declared without %s qualifier",
7639 ekind_capName (unew->ukind),
7640 uentry_getName (unew),
7641 sstate_unparse (oldState),
7642 sstate_unparse (oldState)),
7643 uentry_whereDeclared (unew)))
7644 {
7645 uentry_showWhereSpecified (old);
7646 }
7647 }
28bf4b0b 7648
616915dd 7649 if (vars) unew->info->var->defstate = oldState;
7650 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7651 }
7652}
7653
7654static void
7655 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7656 bool mustConform, bool completeConform)
7657{
7658 alkind newKind;
7659 alkind oldKind;
7660
7661 oldKind = sRef_getAliasKind (old->sref);
7662 newKind = sRef_getAliasKind (unew->sref);
7663
7664 if (alkind_isImplicit (newKind)
7665 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7666 {
7667 if (completeConform && !alkind_equal (newKind, oldKind)
7668 && uentry_isReallySpecified (old))
7669 {
7670 if (optgenerror
7671 (FLG_NEEDSPEC,
7672 message ("%s %q specified as %s, but declared without "
7673 "explicit alias qualifier",
7674 ekind_capName (unew->ukind),
7675 uentry_getName (unew),
7676 alkind_unparse (oldKind)),
7677 uentry_whereDeclared (unew)))
7678 {
7679 uentry_showWhereSpecified (old);
7680 }
7681 }
7682
7683 /*
7684 ** This really shouldn't be necessary, but it is!
7685 ** Function params (?) use new here.
7686 */
7687
7688 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7689 return;
7690 }
7691
7692 if (alkind_isKnown (newKind))
7693 {
7694 if (!alkind_equal (oldKind, newKind))
7695 {
7696 if (alkind_isKnown (oldKind))
7697 {
7698 if (mustConform &&
7699 optgenerror
7700 (FLG_INCONDEFS,
7701 message ("%s %q inconsistently %rdeclared %s %s storage, "
7702 "%s as %s storage",
7703 uentry_ekindName (unew),
7704 uentry_getName (unew),
7705 uentry_isDeclared (old),
7706 fcnErrName (unew),
7707 alkind_unparse (newKind),
7708 uentry_specOrDefName (old),
7709 alkind_unparse (oldKind)),
7710 uentry_whereDeclared (unew)))
7711 {
7712 uentry_showWhereSpecified (old);
7713
28bf4b0b 7714 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7715 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
616915dd 7716 sRef_setAliasKind (old->sref, AK_ERROR,
7717 uentry_whereDeclared (unew));
7718 }
7719 else
7720 {
7721 sRef_setAliasKind (old->sref, newKind,
7722 uentry_whereDeclared (unew));
7723 }
7724 }
7725 else
7726 {
7727 if (!(alkind_isImplicit (newKind)))
7728 {
7729 if (mustConform &&
7730 !uentry_isFunction (unew) &&
7731 optgenerror
7732 (FLG_INCONDEFS,
7733 message ("%s %q inconsistently %rdeclared %s %s storage, "
7734 "implicitly %s as temp storage",
7735 uentry_ekindName (unew),
7736 uentry_getName (unew),
7737 uentry_isDeclared (old),
7738 fcnErrName (unew),
7739 alkind_unparse (newKind),
7740 uentry_specOrDefName (old)),
7741 uentry_whereDeclared (unew)))
7742 {
7743 uentry_showWhereSpecified (old);
7744 oldKind = AK_ERROR;
7745 }
7746
7747 sRef_setAliasKind (old->sref, newKind,
7748 uentry_whereDeclared (unew));
7749 }
7750 else /* newKind is temp or refcounted */
7751 {
7752 ;
7753 }
7754 }
7755 }
7756 }
7757 else /* newKind unknown */
7758 {
7759 ;
7760 }
7761}
7762
7763static void
7764 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7765 bool mustConform, bool completeConform)
7766{
7767 exkind newKind;
7768 exkind oldKind;
7769
7770 oldKind = sRef_getExKind (old->sref);
7771 newKind = sRef_getExKind (unew->sref);
7772
7773 if (exkind_isKnown (newKind))
7774 {
7775 if (oldKind != newKind)
7776 {
7777 if (exkind_isKnown (oldKind))
7778 {
7779 if (mustConform &&
7780 optgenerror
7781 (FLG_INCONDEFS,
7782 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7783 uentry_ekindName (unew),
7784 uentry_getName (unew),
7785 uentry_isDeclared (old),
7786 fcnErrName (unew),
7787 exkind_unparse (newKind),
7788 uentry_specOrDefName (old),
7789 exkind_unparse (oldKind)),
7790 uentry_whereDeclared (unew)))
7791 {
7792 uentry_showWhereSpecified (old);
7793 }
7794
7795 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7796 }
7797 else
7798 {
7799 if (mustConform &&
7800 optgenerror
7801 (FLG_INCONDEFS,
7802 message ("%s %q inconsistently %rdeclared %s %s, "
7803 "implicitly %s without exposure qualifier",
7804 uentry_ekindName (unew),
7805 uentry_getName (unew),
7806 uentry_isDeclared (old),
7807 fcnErrName (unew),
7808 exkind_unparse (newKind),
7809 uentry_specOrDefName (old)),
7810 uentry_whereDeclared (unew)))
7811 {
7812 uentry_showWhereSpecified (old);
7813 }
7814
7815 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7816 }
7817 }
7818 }
7819 else
7820 {
7821 if (completeConform && exkind_isKnown (oldKind)
7822 && uentry_isReallySpecified (old))
7823 {
7824 if (optgenerror
7825 (FLG_NEEDSPEC,
7826 message ("%s %q specified as %s, but declared without "
7827 "exposure qualifier",
7828 ekind_capName (unew->ukind),
7829 uentry_getName (unew),
7830 exkind_unparse (oldKind)),
7831 uentry_whereDeclared (unew)))
7832 {
7833 uentry_showWhereSpecified (old);
7834 }
7835 }
7836
7837 /* yes, this is necessary! (if its a param) */
7838 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7839 }
7840}
7841
28bf4b0b 7842static void
7843checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7844 bool mustConform, /*@unused@*/ bool completeConform)
7845{
7846 valueTable newvals = sRef_getValueTable (unew->sref);
7847
7848 if (valueTable_isDefined (newvals))
7849 {
7850 DPRINTF (("Check meta state: %s -> %s",
7851 uentry_unparseFull (old),
7852 uentry_unparseFull (unew)));
7853
7854 DPRINTF (("Check meta state refs: %s -> %s",
7855 sRef_unparseFull (old->sref),
7856 sRef_unparseFull (unew->sref)));
7857
7858 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7859
7860 /*
7861 ** Copy the new values into the old ref
7862 */
7863
7864 valueTable_elements (newvals, key, newval)
7865 {
7866 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7867 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7868
7869 llassert (metaStateInfo_isDefined (msinfo));
7870
7871 if (stateValue_isUndefined (oldval))
7872 {
7873 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7874 }
7875 else
7876 {
7877 if (stateValue_isError (oldval))
7878 {
7879 if (!stateValue_isError (newval))
7880 {
7881 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7882 }
7883 else
7884 {
7885 ; /* No change necessary. */
7886 }
7887 }
7888 else
7889 {
7890 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7891 {
7892 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7893 {
7894 ;
7895 }
7896 else
7897 {
ccf0a4a8 7898 if (!stateValue_isError (newval)
7899 && !stateValue_isImplicit (newval))
28bf4b0b 7900 {
ccf0a4a8 7901 if (uentry_hasName (unew)
7902 || !sRef_isParam (uentry_getSref (unew)))
7903 {
7904 if (mustConform
7905 && optgenerror
7906 (FLG_INCONDEFS,
7907 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7908 uentry_ekindName (unew),
7909 uentry_getName (unew),
7910 uentry_isDeclared (old),
7911 fcnErrName (unew),
7912 stateValue_unparseValue (newval, msinfo),
7913 uentry_specOrDefName (old),
7914 stateValue_unparseValue (oldval, msinfo)),
7915 uentry_whereDeclared (unew)))
7916 {
7917 uentry_showWhereSpecified (old);
7918 }
7919 }
7920 else
abb1cb43 7921 {
ccf0a4a8 7922 if (mustConform
7923 && optgenerror
7924 (FLG_INCONDEFS,
7925 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7926 uentry_ekindName (unew),
7927 sRef_getParam (uentry_getSref (unew)),
7928 uentry_isDeclared (old),
7929 fcnErrName (unew),
7930 stateValue_unparseValue (newval, msinfo),
7931 uentry_specOrDefName (old),
7932 stateValue_unparseValue (oldval, msinfo)),
7933 uentry_whereDeclared (unew)))
7934 {
7935 uentry_showWhereSpecified (old);
7936 }
abb1cb43 7937 }
28bf4b0b 7938 }
7939 }
7940
7941 DPRINTF (("Updating!"));
7942 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7943 }
7944 else
7945 {
7946 DPRINTF (("Values match"));
7947 }
7948 }
7949 }
7950 } end_valueTable_elements ;
7951 }
7952}
7953
616915dd 7954static void
7955uentry_checkStateConformance (/*@notnull@*/ uentry old,
7956 /*@notnull@*/ uentry unew,
7957 bool mustConform, bool completeConform)
7958{
7959 checkDefState (old, unew, mustConform, completeConform);
7960 checkNullState (old, unew, mustConform, completeConform);
7961 checkAliasState (old, unew, mustConform, completeConform);
7962 checkExpState (old, unew, mustConform, completeConform);
28bf4b0b 7963 checkMetaState (old, unew, mustConform, completeConform);
616915dd 7964
7965 sRef_storeState (old->sref);
7966 sRef_storeState (unew->sref);
7967}
7968
7969static void
7970checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7971{
7972 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7973 {
7974 return;
7975 }
7976
7977 llassert (uentry_isVar (old));
7978 llassert (uentry_isVar (unew));
7979
7980 if (cstring_isEmpty (old->uname))
7981 {
7982 cstring_free (old->uname);
7983 old->uname = cstring_copy (unew->uname);
7984 }
7985
7986 if (unew->info->var->kind == VKRETPARAM
7987 || unew->info->var->kind == VKSEFRETPARAM)
7988 {
7989 if (old->info->var->kind != VKRETPARAM
7990 && old->info->var->kind != VKSEFRETPARAM)
7991 {
7992 if (optgenerror
7993 (FLG_INCONDEFS,
7994 message ("Parameter %q inconsistently %rdeclared as "
7995 "returned parameter",
7996 uentry_getName (unew),
7997 uentry_isDeclared (old)),
7998 uentry_whereDeclared (unew)))
7999 {
8000 uentry_showWhereSpecified (old);
8001 old->info->var->kind = unew->info->var->kind;
8002 }
8003 }
8004 }
8005
8006
8007 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8008 {
8009 if (old->info->var->kind != VKSEFPARAM
8010 && old->info->var->kind != VKSEFRETPARAM)
8011 {
8012 if (optgenerror
8013 (FLG_INCONDEFS,
8014 message ("Parameter %qinconsistently %rdeclared as "
8015 "sef parameter",
8016 uentry_getOptName (unew),
8017 uentry_isDeclared (old)),
8018 uentry_whereDeclared (unew)))
8019 {
8020 uentry_showWhereSpecified (old);
8021 old->info->var->kind = unew->info->var->kind;
8022 }
8023 }
8024 }
8025
8026 if (old->info->var->kind == VKSPEC)
8027 {
8028 old->info->var->kind = unew->info->var->kind;
8029 }
8030 else
8031 {
8032 unew->info->var->kind = old->info->var->kind;
8033 }
8034
8035 if (unew->info->var->checked != CH_UNKNOWN
8036 && unew->info->var->checked != old->info->var->checked)
8037 {
8038 if (old->info->var->checked == CH_UNKNOWN
8039 && !fileloc_isUser (uentry_whereLast (old)))
8040 {
8041 ; /* no error */
8042 }
8043 else
8044 {
8045 if (optgenerror
8046 (FLG_INCONDEFS,
8047 message ("Variable %q inconsistently %rdeclared as "
8048 "%s parameter (was %s)",
8049 uentry_getName (unew),
8050 uentry_isDeclared (old),
8051 checkedName (unew->info->var->checked),
8052 checkedName (old->info->var->checked)),
8053 uentry_whereDeclared (unew)))
8054 {
8055 uentry_showWhereSpecified (old);
8056 }
8057 }
8058
8059 old->info->var->checked = unew->info->var->checked;
8060 }
8061 else
8062 {
8063 if (completeConform
8064 && (old->info->var->checked != CH_UNKNOWN)
8065 && uentry_isReallySpecified (old))
8066 {
8067 if (optgenerror
8068 (FLG_NEEDSPEC,
8069 message ("%s %q specified as %s, but declared without %s qualifier",
8070 ekind_capName (unew->ukind),
8071 uentry_getName (unew),
8072 checkedName (old->info->var->checked),
8073 checkedName (old->info->var->checked)),
8074 uentry_whereDeclared (unew)))
8075 {
8076 uentry_showWhereSpecified (old);
8077 }
8078 }
8079
8080 unew->info->var->checked = old->info->var->checked;
8081 }
8082
8083 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8084}
8085
8086void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8087{
8088 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8089 {
8090 return;
8091 }
8092
8093 llassert (uentry_isVar (u1));
8094 llassert (uentry_isVar (u2));
8095
8096 if (u1->info->var->kind != u2->info->var->kind) {
8097 if (u1->info->var->kind == VKSEFRETPARAM) {
8098 if (u2->info->var->kind == VKRETPARAM) {
8099 voptgenerror
8100 (FLG_TYPE,
8101 message ("Function types are inconsistent. Parameter %d is "
8102 "sef parameter, but non-sef parameter in "
8103 "assigned function: %s",
8104 paramno, exprNode_unparse (e)),
8105 exprNode_loc (e));
8106 } else if (u2->info->var->kind == VKSEFPARAM) {
8107 voptgenerror
8108 (FLG_TYPE,
8109 message ("Function types are inconsistent. Parameter %d is "
8110 "returns parameter, but non-returns parameter in "
8111 "assigned function: %s",
8112 paramno, exprNode_unparse (e)),
8113 exprNode_loc (e));
8114 } else {
8115 voptgenerror
8116 (FLG_TYPE,
8117 message ("Function types are inconsistent. Parameter %d is "
8118 "sef returns parameter, but non-sef returns parameter in "
8119 "assigned function: %s",
8120 paramno, exprNode_unparse (e)),
8121 exprNode_loc (e));
8122 }
8123 } else if (u1->info->var->kind == VKRETPARAM) {
8124 voptgenerror
8125 (FLG_TYPE,
8126 message ("Function types are inconsistent. Parameter %d is "
8127 "returns parameter, but non-returns parameter in "
8128 "assigned function: %s",
8129 paramno, exprNode_unparse (e)),
8130 exprNode_loc (e));
8131 } else if (u1->info->var->kind == VKSEFPARAM) {
8132 voptgenerror
8133 (FLG_TYPE,
8134 message ("Function types are inconsistent. Parameter %d is "
8135 "sef parameter, but non-sef parameter in "
8136 "assigned function: %s",
8137 paramno, exprNode_unparse (e)),
8138 exprNode_loc (e));
8139 } else {
8140 if (u2->info->var->kind == VKSEFRETPARAM) {
8141 voptgenerror
8142 (FLG_TYPE,
8143 message ("Function types are inconsistent. Parameter %d is "
8144 "normal parameter, but sef returns parameter in "
8145 "assigned function: %s",
8146 paramno, exprNode_unparse (e)),
8147 exprNode_loc (e));
8148 } else if (u2->info->var->kind == VKSEFPARAM) {
8149 voptgenerror
8150 (FLG_TYPE,
8151 message ("Function types are inconsistent. Parameter %d is "
8152 "normal parameter, but sef parameter in "
8153 "assigned function: %s",
8154 paramno, exprNode_unparse (e)),
8155 exprNode_loc (e));
8156 } else if (u2->info->var->kind == VKRETPARAM) {
8157 voptgenerror
8158 (FLG_TYPE,
8159 message ("Function types are inconsistent. Parameter %d is "
8160 "normal parameter, but returns parameter in "
8161 "assigned function: %s",
8162 paramno, exprNode_unparse (e)),
8163 exprNode_loc (e));
8164 } else {
8165 BADBRANCH;
8166 }
8167 }
8168 }
8169
8170 if (u1->info->var->defstate != u2->info->var->defstate)
8171 {
8172 voptgenerror
8173 (FLG_TYPE,
8174 message ("Function types are inconsistent. Parameter %d is "
8175 "%s, but %s in assigned function: %s",
8176 paramno,
8177 sstate_unparse (u1->info->var->defstate),
8178 sstate_unparse (u2->info->var->defstate),
8179 exprNode_unparse (e)),
8180 exprNode_loc (e));
8181 }
8182
8183 if (u1->info->var->nullstate != u2->info->var->nullstate)
8184 {
8185 voptgenerror
8186 (FLG_TYPE,
8187 message ("Function types are inconsistent. Parameter %d is "
8188 "%s, but %s in assigned function: %s",
8189 paramno,
8190 nstate_unparse (u1->info->var->nullstate),
8191 nstate_unparse (u2->info->var->nullstate),
8192 exprNode_unparse (e)),
8193 exprNode_loc (e));
8194 }
8195
8196 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8197 {
8198 voptgenerror
8199 (FLG_TYPE,
8200 message ("Function types are inconsistent. Parameter %d is "
8201 "%s, but %s in assigned function: %s",
8202 paramno,
8203 alkind_unparse (sRef_getAliasKind (u1->sref)),
8204 alkind_unparse (sRef_getAliasKind (u2->sref)),
8205 exprNode_unparse (e)),
8206 exprNode_loc (e));
8207 }
8208
8209 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8210 {
8211 voptgenerror
8212 (FLG_TYPE,
8213 message ("Function types are inconsistent. Parameter %d is "
8214 "%s, but %s in assigned function: %s",
8215 paramno,
8216 exkind_unparse (sRef_getExKind (u1->sref)),
8217 exkind_unparse (sRef_getExKind (u2->sref)),
8218 exprNode_unparse (e)),
8219 exprNode_loc (e));
8220 }
8221}
8222
8223static void
8224checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8225 /*@notnull@*/ uentry unew,
8226 bool mustConform, /*@unused@*/ bool completeConform)
8227{
8228 uentryList oldParams = uentry_getParams (old);
8229 uentryList newParams = uentry_getParams (unew);
8230 ctype newType = unew->utype;
ac35a6ab 8231 ctype oldType = ctype_realType (old->utype);
616915dd 8232 ctype oldRetType = ctype_unknown;
8233 ctype newRetType = ctype_unknown;
8234
28bf4b0b 8235 DPRINTF (("Function conform: %s ==> %s",
8236 uentry_unparseFull (old),
8237 uentry_unparseFull (unew)));
8238
616915dd 8239 if (uentry_isForward (old))
8240 {
8241 mustConform = FALSE;
efd360a3 8242 uentry_updateInto (old, unew);
616915dd 8243 return;
8244 }
8245
8246 /*
8247 ** check return values
8248 */
8249
8250 if (ctype_isKnown (oldType))
8251 {
8252 llassert (ctype_isFunction (oldType));
28bf4b0b 8253 oldRetType = ctype_getReturnType (oldType);
616915dd 8254 }
8255
8256 if (ctype_isKnown (newType))
8257 {
8258 llassert (ctype_isFunction (newType));
28bf4b0b 8259 newRetType = ctype_getReturnType (newType);
616915dd 8260 }
8261
8262 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8263 && !ctype_matchDef (newRetType, oldRetType))
8264 {
8265 if (mustConform) returnValueError (old, unew);
8266 }
8267 else
8268 {
8269 if (ctype_isConj (newRetType))
8270 {
8271 if (ctype_isConj (oldRetType))
8272 {
8273 if (!ctype_sameAltTypes (newRetType, oldRetType))
8274 {
8275 if (optgenerror
8276 (FLG_INCONDEFS,
8277 message ("Function %q inconsistently %rdeclared to "
8278 "return alternate types %s "
8279 "(types match, but alternates are not identical, "
8280 "so checking may not be correct)",
8281 uentry_getName (unew),
8282 uentry_isDeclared (old),
8283 ctype_unparse (newRetType)),
8284 uentry_whereDeclared (unew)))
8285 {
8286 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8287 }
8288 }
8289 }
8290 else
8291 {
8292 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8293 }
8294 }
8295 }
8296
28bf4b0b 8297 DPRINTF (("Before state: %s",
8298 uentry_unparseFull (old)));
616915dd 8299 uentry_checkStateConformance (old, unew, mustConform, completeConform);
28bf4b0b 8300 DPRINTF (("After state: %s",
8301 uentry_unparseFull (old)));
616915dd 8302
8303 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8304 {
8305 if (exitkind_isKnown (unew->info->fcn->exitCode))
8306 {
8307 if (optgenerror
8308 (FLG_INCONDEFS,
8309 message ("Function %q inconsistently %rdeclared using %s",
8310 uentry_getName (unew),
8311 uentry_isDeclared (old),
8312 exitkind_unparse (unew->info->fcn->exitCode)),
8313 uentry_whereDeclared (unew)))
8314 {
8315 uentry_showWhereSpecified (old);
8316 }
8317 }
8318 else
8319 {
8320 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8321 }
8322 }
8323
8324 if (!qual_isUnknown (unew->info->fcn->nullPred))
8325 {
28bf4b0b 8326 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
616915dd 8327 {
8328 if (optgenerror
8329 (FLG_INCONDEFS,
8330 message ("Function %q inconsistently %rdeclared using %s",
8331 uentry_getName (unew),
8332 uentry_isDeclared (old),
8333 qual_unparse (unew->info->fcn->nullPred)),
8334 uentry_whereDeclared (unew)))
8335 {
8336 uentry_showWhereSpecified (old);
8337 }
8338 }
8339 }
8340 else
8341 {
8342 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8343 }
8344
8345 if (unew->info->fcn->specialCode != SPC_NONE)
8346 {
8347 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8348 {
8349 if (optgenerror
8350 (FLG_INCONDEFS,
8351 message ("Function %q inconsistently %rdeclared using %s",
8352 uentry_getName (unew),
8353 uentry_isDeclared (old),
8354 specCode_unparse (unew->info->fcn->specialCode)),
8355 uentry_whereDeclared (unew)))
8356 {
8357 uentry_showWhereSpecified (old);
8358 }
8359 }
8360 }
8361 else
8362 {
8363 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8364 }
8365
8366 /*
8367 ** check parameters
8368 */
8369
8370 if (!uentryList_sameObject (oldParams, newParams)
8371 && (!uentryList_isMissingParams (oldParams)))
8372 {
8373 if (!uentryList_isMissingParams (newParams))
8374 {
8375 int paramno = 0;
8376 int nparams = uentryList_size (oldParams);
8377 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8378
8379 if (nparams != uentryList_size (newParams))
8380 {
8381 nargsError (old, unew);
8382 }
8383
8384 if (uentryList_size (newParams) < nparams)
8385 {
8386 nparams = uentryList_size (newParams);
8387 }
8388
8389 while (paramno < nparams)
8390 {
8391 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8392 uentry newCurrent = uentryList_getN (newParams, paramno);
8393 ctype oldCurrentType = uentry_getType (oldCurrent);
8394 ctype newCurrentType = uentry_getType (newCurrent);
8395
8396 llassert (uentry_isValid (oldCurrent)
8397 && uentry_isValid (newCurrent));
8398
8399 if (!uentry_isElipsisMarker (oldCurrent)
8400 && !uentry_isElipsisMarker (newCurrent))
8401 {
8402 checkVarConformance (oldCurrent, newCurrent,
8403 mustConform, completeConform);
8404 }
8405
8406 if (checknames)
8407 {
8408 if (uentry_hasName (oldCurrent)
8409 && uentry_hasName (newCurrent))
8410 {
8411 cstring oldname = uentry_getName (oldCurrent);
8412 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8413 cstring oname;
8414 cstring nname = uentry_getName (newCurrent);
8415 cstring nnamefix;
8416
8417 if (cstring_isDefined (pfx)
68de3f33 8418 && cstring_equalPrefix (oldname, pfx))
616915dd 8419 {
8420 oname = cstring_suffix (oldname, cstring_length (pfx));
8421 }
8422 else
8423 {
8424 oname = oldname;
8425 /*@-branchstate@*/ } /*@=branchstate@*/
8426
8427 if (cstring_isDefined (pfx)
68de3f33 8428 && cstring_equalPrefix (nname, pfx))
616915dd 8429 {
8430 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8431 }
8432 else
8433 {
8434 nnamefix = nname;
8435 /*@-branchstate@*/ } /*@=branchstate@*/
8436
8437 if (!cstring_equal (oname, nnamefix))
8438 {
8439 if (optgenerror
8440 (FLG_DECLPARAMMATCH,
8441 message ("Definition parameter name %s does not match "
8442 "name of corresponding parameter in "
8443 "declaration: %s",
8444 nnamefix, oname),
8445 uentry_whereLast (newCurrent)))
8446 {
8447 uentry_showWhereLastPlain (oldCurrent);
8448 }
8449 }
8450
8451 cstring_free (oldname);
8452 cstring_free (nname);
8453 }
8454 }
8455
8456 if (!ctype_match (oldCurrentType, newCurrentType))
8457 {
8458 paramTypeError (old, oldCurrent, oldCurrentType,
8459 unew, newCurrent, newCurrentType, paramno);
8460 }
8461 else
8462 {
8463 if (ctype_isMissingParamsMarker (newCurrentType)
8464 || ctype_isElips (newCurrentType)
8465 || ctype_isMissingParamsMarker (oldCurrentType)
8466 || ctype_isElips (oldCurrentType))
8467 {
8468 ;
8469 }
8470 else
8471 {
8472 if (ctype_isConj (newCurrentType))
8473 {
8474 if (ctype_isConj (oldCurrentType))
8475 {
8476 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8477 {
8478 if (optgenerror
8479 (FLG_INCONDEFS,
8480 message ("Parameter %q inconsistently %rdeclared with "
8481 "alternate types %s "
8482 "(types match, but alternates are not identical, "
8483 "so checking may not be correct)",
8484 uentry_getName (newCurrent),
8485 uentry_isDeclared (oldCurrent),
8486 ctype_unparse (newCurrentType)),
8487 uentry_whereDeclared (unew)))
8488 {
8489 uentry_showWhereLastVal (oldCurrent,
8490 ctype_unparse (oldCurrentType));
8491 }
8492 }
8493 }
8494 else
8495 {
8496 if (optgenerror
8497 (FLG_INCONDEFS,
8498 message ("Parameter %q inconsistently %rdeclared with "
8499 "alternate types %s",
8500 uentry_getName (newCurrent),
8501 uentry_isDeclared (oldCurrent),
8502 ctype_unparse (newCurrentType)),
8503 uentry_whereDeclared (unew)))
8504 {
8505 uentry_showWhereLastVal (oldCurrent,
8506 ctype_unparse (oldCurrentType));
8507
8508 }
8509 }
8510 }
8511 else
8512 {
8513 if (ctype_isConj (oldCurrentType))
8514 {
8515 uentry_setType (newCurrent, oldCurrentType);
8516 }
8517 }
8518 }
8519 }
8520
8521 paramno++;
8522 /*
8523 ** Forgot this! detected by lclint:
8524 ** uentry.c:1257,15: Suspected infinite loop
8525 */
8526 }
8527 }
8528 }
8529
8530 if (!uentryList_isMissingParams (newParams))
8531 {
8532 if (ctype_isConj (oldRetType))
8533 {
8534 old->utype = ctype_makeFunction (oldRetType,
8535 uentryList_copy (newParams));
8536 }
8537 else
8538 {
8539 old->utype = unew->utype;
8540 }
8541 }
8542
8543 checkGlobalsConformance (old, unew, mustConform, completeConform);
8544 checkModifiesConformance (old, unew, mustConform, completeConform);
8545
28bf4b0b 8546 DPRINTF (("Before list: %s",
8547 uentry_unparseFull (old)));
8548
8549 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
616915dd 8550 {
28bf4b0b 8551 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
616915dd 8552 {
28bf4b0b 8553 /*
616915dd 8554 if (optgenerror
8555 (FLG_INCONDEFS,
8556 message ("Function %q redeclared using special clauses (can only "
8557 "be used in first declaration)",
8558 uentry_getName (unew)),
8559 uentry_whereDeclared (unew)))
8560 {
8561 uentry_showWhereLast (old);
8562 }
28bf4b0b 8563 */
8564
8565 /*@i23 need checking @*/
8566
8567 old->info->fcn->specclauses = unew->info->fcn->specclauses;
616915dd 8568 }
8569 else
8570 {
28bf4b0b 8571 /*@i43 should be able to append? @*/
8572
8573 stateClauseList_checkEqual (old, unew);
8574 stateClauseList_free (unew->info->fcn->specclauses);
8575 unew->info->fcn->specclauses = stateClauseList_undefined;
8576 /*@-branchstate@*/
616915dd 8577 }
8578 }
146e25eb 8579 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
616915dd 8580
8581 if (fileloc_isUndefined (old->whereDeclared))
8582 {
8583 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8584 }
8585 else if (fileloc_isUndefined (unew->whereDeclared))
8586 {
8587 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8588 }
8589 else
8590 {
8591 /* no change */
8592 }
146e25eb 8593/*@i523 @*/ }
616915dd 8594
8595void
8596uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8597{
8598 multiVal uval;
8599
8600 llassert (uentry_isValid (ue));
8601 llassert (uentry_isEitherConstant (ue));
8602
b9904f57 8603 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8604 uval = uentry_getConstantValue (ue);
616915dd 8605
8606 if (multiVal_isDefined (uval))
8607 {
8608 if (multiVal_isDefined (m))
8609 {
8610 if (!multiVal_equiv (uval, m))
8611 {
8612 if (optgenerror
8613 (FLG_INCONDEFS,
8614 message ("%s %q defined with inconsistent value: %q",
8615 ekind_capName (ue->ukind),
8616 uentry_getName (ue),
8617 multiVal_unparse (m)),
8618 g_currentloc))
8619 {
8620 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8621 }
8622 }
8623 }
8624 multiVal_free (m);
8625 }
8626 else
8627 {
b9904f57 8628 uentry_setConstantValue (ue, m);
616915dd 8629 }
8630}
8631
8632static
8633bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8634 bool mustConform)
8635{
8636 bool typeError = FALSE;
8637
8638 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8639 {
8640 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8641 {
8642 if (mustConform)
8643 {
28bf4b0b 8644 DPRINTF (("Check struct conformance: %s / %s",
8645 uentry_unparseFull (old),
8646 uentry_unparseFull (unew)));
616915dd 8647 checkStructConformance (old, unew);
8648 }
8649 }
8650 else
8651 {
8652 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8653 {
8654 llbug (message ("struct tags: bad types: %t / %t",
8655 old->utype, unew->utype));
8656 }
8657 }
8658 }
8659 else if (uentry_isEnumTag (old))
8660 {
8661 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8662 {
8663 if (mustConform) checkEnumConformance (old, unew);
8664 }
8665 else
8666 {
8667 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8668 {
8669 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8670 ctype_unparse (unew->utype)));
8671 }
8672 }
8673 }
8674 else if (!ctype_match (old->utype, unew->utype))
8675 {
28bf4b0b 8676 DPRINTF (("Type mismatch: %s / %s",
8677 ctype_unparse (old->utype),
8678 ctype_unparse (unew->utype)));
8679
616915dd 8680 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8681 {
8682 ctype realt = ctype_realType (unew->utype);
8683
8684 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8685 {
8686 unew->utype = ctype_bool;
8687 }
8688 else
8689 {
8690 if (mustConform)
8691 {
8692 typeError = optgenerror
8693 (FLG_INCONDEFS,
8694 message ("%q defined as %s", uentry_getName (old),
8695 ctype_unparse (realt)),
8696 uentry_whereDeclared (unew));
8697 }
8698 }
8699 }
8700 else
8701 {
8702 if (mustConform)
8703 {
8704 ctype oldr = ctype_realType (old->utype);
8705 ctype newr = ctype_realType (unew->utype);
8706
8707 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8708 {
8709 checkStructConformance (old, unew);
8710 }
8711 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8712 {
8713 checkStructConformance (old, unew);
8714 }
8715 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8716 {
8717 checkEnumConformance (old, unew);
8718 }
8719 else if (uentry_isConstant (old)
8720 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8721 {
8722 /* okay...for now! (should check the type is reset later... */
8723 }
8724 else
8725 {
8726 DPRINTF (("YABA!"));
8727 if (optgenerror
8728 (FLG_INCONDEFS,
8729 message ("%s %q %rdeclared with inconsistent type: %t",
8730 ekind_capName (unew->ukind),
8731 uentry_getName (unew),
8732 uentry_isDeclared (old),
8733 unew->utype),
8734 uentry_whereDeclared (unew)))
8735 {
8736 uentry_showWhereLast (old);
8737 typeError = TRUE;
8738 }
8739 }
8740 }
8741 }
8742 }
8743 else
8744 {
8745 /* no error */
8746 }
8747
8748 return typeError;
8749}
8750
8751static void
8752uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8753 /*@notnull@*/ uentry unew,
8754 bool mustConform, bool completeConform)
8755{
8756 if (ctype_isDefined (unew->info->datatype->type))
8757 {
8758 /*
8759 ** bool is hard coded here, since it is built into LCL.
8760 ** For now, we're stuck with LCL's types.
8761 */
8762
8763 if (ctype_isDirectBool (old->utype) &&
8764 cstring_equalLit (unew->uname, "bool"))
8765 {
8766 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8767 evs 2000-07-25: removed
8768 */
8769 unew->utype = ctype_bool;
8770 }
8771
8772 if (ctype_isUnknown (old->info->datatype->type))
8773 {
8774 old->info->datatype->type = unew->info->datatype->type;
8775 }
8776 else
8777 {
8778 DPRINTF (("Old: %s / New: %s",
8779 uentry_unparseFull (old),
8780 uentry_unparseFull (unew)));
8781 DPRINTF (("Types: %s / %s",
8782 ctype_unparse (old->info->datatype->type),
8783 ctype_unparse (unew->info->datatype->type)));
8784
8785 if (ctype_matchDef (old->info->datatype->type,
8786 unew->info->datatype->type))
8787 {
8788 ;
8789 }
8790 else
8791 {
8792 if (optgenerror
8793 (FLG_INCONDEFS,
8794 message
8795 ("Type %q %s with inconsistent type: %t",
8796 uentry_getName (unew),
8797 uentry_reDefDecl (old, unew),
8798 unew->info->datatype->type),
8799 uentry_whereDeclared (unew)))
8800 {
8801 uentry_showWhereLastExtra
8802 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8803 }
8804
8805 old->info->datatype->type = unew->info->datatype->type;
8806 }
8807 }
8808 }
8809
8810 if (unew->info->datatype->abs != MAYBE)
8811 {
8812 if (ynm_isOff (old->info->datatype->abs)
8813 && ynm_isOn (unew->info->datatype->abs))
8814 {
8815 if (!ctype_isDirectBool (old->utype))
8816 {
8817 if (optgenerror
8818 (FLG_INCONDEFS,
8819 message
8820 ("Datatype %q inconsistently %rdeclared as abstract type",
8821 uentry_getName (unew),
8822 uentry_isDeclared (old)),
8823 uentry_whereDeclared (unew)))
8824 {
8825 uentry_showWhereLastPlain (old);
8826 }
8827 }
8828 }
8829 else if (ynm_isOn (old->info->datatype->abs)
8830 && ynm_isOff (unew->info->datatype->abs))
8831 {
8832 if (!ctype_isDirectBool (old->utype))
8833 {
8834 if (optgenerror
8835 (FLG_INCONDEFS,
8836 message
8837 ("Datatype %q inconsistently %rdeclared as concrete type",
8838 uentry_getName (unew),
8839 uentry_isDeclared (old)),
8840 uentry_whereDeclared (unew)))
8841 {
8842 uentry_showWhereLastPlain (old);
8843 }
8844 }
8845 }
8846 else
8847 {
8848 ;
8849 }
8850 }
8851 else
8852 {
8853 if (ynm_isOn (old->info->datatype->abs))
8854 {
8855 old->sref = unew->sref;
8856 unew->info->datatype->mut = old->info->datatype->mut;
8857
8858 if (completeConform
8859 && uentry_isReallySpecified (old))
8860 {
8861 if (optgenerror
8862 (FLG_NEEDSPEC,
8863 message
8864 ("Datatype %q specified as abstract, "
8865 "but abstract annotation not used in declaration",
8866 uentry_getName (unew)),
8867 uentry_whereDeclared (unew)))
8868 {
8869 uentry_showWhereLastPlain (old);
8870 }
8871 }
8872 }
8873 }
8874
8875 unew->info->datatype->abs = old->info->datatype->abs;
8876
8877 if (ynm_isMaybe (unew->info->datatype->mut))
8878 {
8879 if (completeConform && ynm_isOff (old->info->datatype->mut)
8880 && uentry_isReallySpecified (old))
8881 {
8882 if (optgenerror
8883 (FLG_NEEDSPEC,
8884 message
8885 ("Datatype %q specified as immutable, "
8886 "but immutable annotation not used in declaration",
8887 uentry_getName (unew)),
8888 uentry_whereDeclared (unew)))
8889 {
8890 uentry_showWhereLastPlain (old);
8891 }
8892 }
8893
8894 unew->info->datatype->mut = old->info->datatype->mut;
8895 }
8896 else if (ynm_isMaybe (old->info->datatype->mut))
8897 {
8898 old->info->datatype->mut = unew->info->datatype->mut;
8899 }
8900 else
8901 {
8902 if (ynm_isOn (old->info->datatype->abs))
8903 {
8904 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8905 {
8906 if (optgenerror
8907 (FLG_INCONDEFS,
8908 message ("Datatype %q inconsistently %rdeclared as immutable",
8909 uentry_getName (unew),
8910 uentry_isDeclared (old)),
8911 uentry_whereDeclared (unew)))
8912 {
8913 uentry_showWhereLastPlain (old);
8914 }
8915 }
8916 else
8917 {
8918 if (ynm_isOff (old->info->datatype->mut)
8919 && ynm_isOn (unew->info->datatype->mut))
8920 {
8921 if (optgenerror
8922 (FLG_INCONDEFS,
8923 message ("Datatype %q inconsistently %rdeclared as mutable",
8924 uentry_getName (unew),
8925 uentry_isDeclared (old)),
8926 uentry_whereDeclared (unew)))
8927 {
8928 uentry_showWhereLastPlain (old);
8929 }
8930 }
8931 }
8932 }
8933 old->info->datatype->mut = unew->info->datatype->mut;
8934 }
8935
8936 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8937}
8938
8939static void
8940uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8941 /*@notnull@*/ uentry unew,
8942 bool mustConform,
8943 /*@unused@*/ bool completeConform)
8944{
b9904f57 8945 multiVal oldval = uentry_getConstantValue (old);
8946 multiVal newval = uentry_getConstantValue (unew);
616915dd 8947
b9904f57 8948 if (multiVal_isDefined (oldval))
616915dd 8949 {
b9904f57 8950 if (multiVal_isDefined (newval))
616915dd 8951 {
b9904f57 8952 if (!multiVal_equiv (oldval, newval))
616915dd 8953 {
8954 if (mustConform
8955 && optgenerror
8956 (FLG_INCONDEFS,
8957 message ("%s %q %rdeclared with inconsistent value: %q",
8958 ekind_capName (unew->ukind),
8959 uentry_getName (unew),
8960 uentry_isDeclared (old),
b9904f57 8961 multiVal_unparse (newval)),
616915dd 8962 uentry_whereDeclared (unew)))
8963 {
b9904f57 8964 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
616915dd 8965 }
8966 }
8967
b9904f57 8968 uentry_setConstantValue (unew, multiVal_copy (oldval));
616915dd 8969 }
8970 else
8971 {
8972 ;
8973 }
8974 }
8975 else
8976 {
b9904f57 8977 uentry_setConstantValue (old, multiVal_copy (newval));
616915dd 8978 }
8979}
8980
8981static void
8982uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8983 /*@notnull@*/ uentry unew, bool mustConform,
8984 bool completeConform)
8985{
8986 bool typeError = FALSE;
8987 bool fcnConformance = FALSE;
8988
8989 if (!ekind_equal (unew->ukind, old->ukind))
8990 {
8991 /*
8992 ** okay, only if one is a function and the other is
8993 ** a variable of type function.
8994 */
8995
8996 if (unew->ukind == KENUMCONST
8997 && old->ukind == KCONST)
8998 {
8999 old->ukind = KENUMCONST;
9000 goto nokinderror;
9001 }
9002
9003 if (unew->ukind == KFCN
9004 && old->ukind == KCONST
9005 && ctype_isUnknown (old->utype))
9006 {
9007 /*
9008 ** When a function is defined with an unparam macro
9009 */
9010
efd360a3 9011 uentry_updateInto (old, unew);
616915dd 9012 return;
9013 }
9014
9015 if (uentry_isExpandedMacro (old)
9016 && uentry_isEitherConstant (unew))
9017 {
efd360a3 9018 uentry_updateInto (old, unew);
616915dd 9019 return;
9020 }
9021
9022 if (uentry_isEndIter (unew))
9023 {
9024 if (ctype_isUnknown (old->utype))
9025 {
9026 if (!uentry_isSpecified (old)
9027 && uentry_isCodeDefined (unew))
9028 {
9029 if (!fileloc_withinLines (uentry_whereDefined (old),
9030 uentry_whereDeclared (unew), 2))
9031 { /* bogus! will give errors if there is too much whitespace */
9032 voptgenerror
9033 (FLG_SYNTAX,
9034 message
9035 ("Iterator finalized name %q does not match name in "
9036 "previous iter declaration (should be end_%q). This iter "
9037 "is declared at %q",
9038 uentry_getName (unew),
9039 uentry_getName (old),
9040 fileloc_unparse (uentry_whereDefined (old))),
9041 uentry_whereDeclared (old));
9042 }
9043 }
9044
efd360a3 9045 uentry_updateInto (old, unew);
616915dd 9046 return;
9047 }
9048 else
9049 {
9050 KindConformanceError (old, unew, mustConform);
9051 }
9052 }
9053
9054 if (uentry_isFunction (unew))
9055 {
9056 if (uentry_isVariable (old))
9057 {
9058 if (!ctype_isUnknown (old->utype))
9059 {
9060 if (ctype_isFunction (old->utype))
9061 {
9062 uentry_makeVarFunction (old);
9063 checkFunctionConformance (old, unew, mustConform,
9064 completeConform);
9065 fcnConformance = TRUE;
9066 }
9067 else
9068 {
9069 KindConformanceError (old, unew, mustConform);
9070 }
9071 }
9072 else
9073 {
9074 if (uentry_isExpandedMacro (old))
9075 {
9076 if (fileloc_isUndefined (unew->whereDefined))
9077 {
9078 unew->whereDefined = fileloc_update (unew->whereDefined,
9079 old->whereDefined);
9080 }
9081
efd360a3 9082 uentry_updateInto (old, unew);
616915dd 9083 old->used = unew->used = TRUE;
9084 return;
9085 }
9086 else
9087 {
9088 /* undeclared identifier */
9089 old->utype = unew->utype;
9090 uentry_makeVarFunction (old);
9091 checkFunctionConformance (old, unew, FALSE, FALSE);
9092 fcnConformance = TRUE;
9093 }
9094 }
9095 }
9096 else
9097 {
9098 KindConformanceError (old, unew, mustConform);
9099 }
9100 }
9101 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9102 {
9103 if (!ctype_isUnknown (unew->utype))
9104 {
9105 if (ctype_isFunction (unew->utype))
9106 {
9107 uentry_makeVarFunction (unew);
9108 checkFunctionConformance (old, unew, mustConform, completeConform);
9109 fcnConformance = TRUE;
9110 }
9111 else
9112 {
9113 KindConformanceError (old, unew, mustConform);
9114 }
9115 }
9116 else
9117 {
9118 KindConformanceError (old, unew, mustConform);
9119 }
9120 }
9121 else
9122 {
9123 KindConformanceError (old, unew, mustConform);
9124 }
9125 }
9126 else
9127 {
9128 /*
9129 ** check parameter lists for functions
9130 ** (before type errors, to get better messages
9131 */
9132
9133 if (uentry_isFunction (old))
9134 {
9135 checkFunctionConformance (old, unew, mustConform, completeConform);
9136 fcnConformance = TRUE;
9137 }
9138 else
9139 {
9140 if (!ctype_isUndefined (old->utype))
9141 {
9142 typeError = checkTypeConformance (old, unew, mustConform);
9143 }
9144 }
9145 }
9146
9147 nokinderror:
9148
9149 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9150 {
9151 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9152 }
9153
9154 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9155 {
9156 DPRINTF (("Check datatype: %s / %s",
9157 uentry_unparseFull (old),
9158 uentry_unparseFull (unew)));
9159
9160 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9161 }
9162
9163 if (uentry_isVariable (old) && uentry_isVariable (unew))
9164 {
9165 if (!typeError &&
9166 !ctype_matchDef (old->utype, unew->utype))
9167 {
9168 if (optgenerror
9169 (FLG_INCONDEFS,
9170 message
9171 ("Variable %q %s with inconsistent type (arrays and pointers are "
9172 "not identical in variable declarations): %t",
9173 uentry_getName (unew),
9174 uentry_reDefDecl (old, unew),
9175 unew->utype),
9176 uentry_whereDeclared (unew)))
9177 {
9178 uentry_showWhereLast (old);
9179
9180 /*
9181 ** Avoid repeated errors.
9182 */
9183
9184 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9185 {
9186 old->whereDefined = fileloc_update (old->whereDefined,
9187 fileloc_undefined);
9188 }
9189
9190 typeError = TRUE;
9191 }
9192 }
9193
9194 checkVarConformance (old, unew, mustConform, completeConform);
9195 }
9196
9197 if (fcnConformance)
9198 {
9199 /* old->utype = unew->utype; */
9200 }
9201 else
9202 {
9203 if (ctype_isConj (old->utype))
9204 {
9205 if (ctype_isConj (unew->utype))
9206 {
9207 if (!ctype_sameAltTypes (old->utype, unew->utype))
9208 {
9209 if (optgenerror
9210 (FLG_INCONDEFS,
9211 message ("%s %q inconsistently %rdeclared with "
9212 "alternate types %s "
9213 "(types match, but alternates are not identical, "
9214 "so checking may not be correct)",
9215 ekind_capName (uentry_getKind (old)),
9216 uentry_getName (unew),
9217 uentry_isDeclared (old),
9218 ctype_unparse (unew->utype)),
9219 uentry_whereDeclared (unew)))
9220 {
9221 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9222 }
9223 else
9224 {
9225 old->utype = unew->utype;
9226 }
9227 }
9228 }
9229 }
9230 else
9231 {
9232 if (ctype_isUnknown (old->utype))
9233 {
9234 old->utype = unew->utype;
9235 }
9236 }
9237 }
9238
9239 if (unew->ukind == old->ukind)
9240 {
9241 sfree (unew->info);
9242 unew->info = uinfo_copy (old->info, old->ukind);
9243 }
9244
9245 sRef_storeState (old->sref);
9246 sRef_storeState (unew->sref);
9247}
9248
ba45e1e4 9249static void uentry_mergeConstraints (uentry spec, uentry def)
9250{
9251 if (uentry_isFunction (def))
9252 {
9253 DPRINTF (("Here: %s / %s",
9254 uentry_unparseFull (spec),
9255 uentry_unparseFull (def)));
efd360a3 9256 /* evans 2001-07-21 */
9257 llassert (uentry_isFunction (spec));
ba45e1e4 9258
9259 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9260 {
9261 if (fileloc_isXHFile (uentry_whereLast (def)))
9262 {
9263 llassert (uentry_isFunction (spec));
9264 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9265 def->info->fcn->preconditions);
ba45e1e4 9266 }
ccf0a4a8 9267 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9268 {
9269 ;
9270 }
ba45e1e4 9271 else
9272 {
ccf0a4a8 9273 /* Check if the constraints are identical */
9274
3120b462 9275 if (optgenerror
9276 (FLG_INCONDEFS,
9277 message
9278 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9279 uentry_getName (spec),
9280 functionConstraint_unparse (spec->info->fcn->preconditions)),
9281 uentry_whereLast (def)))
9282 {
9283 uentry_showWhereSpecified (spec);
9284 }
9285
9286 functionConstraint_free (spec->info->fcn->preconditions);
9287 spec->info->fcn->preconditions = def->info->fcn->preconditions;
ba45e1e4 9288 }
3120b462 9289
9290 def->info->fcn->preconditions = functionConstraint_undefined;
ba45e1e4 9291 }
9292
ba45e1e4 9293 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9294 {
9295 if (fileloc_isXHFile (uentry_whereLast (def)))
9296 {
9297 llassert (uentry_isFunction (spec));
9298 DPRINTF (("Post: %s /++/ %s",
9299 functionConstraint_unparse (spec->info->fcn->postconditions),
9300 functionConstraint_unparse (def->info->fcn->postconditions)));
9301 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9302 def->info->fcn->postconditions);
9303 def->info->fcn->postconditions = functionConstraint_undefined;
9304 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9305 }
9306 else
9307 {
3120b462 9308 if (optgenerror
9309 (FLG_INCONDEFS,
9310 message
9311 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9312 uentry_getName (spec),
9313 functionConstraint_unparse (spec->info->fcn->postconditions)),
9314 uentry_whereLast (def)))
9315 {
9316 uentry_showWhereSpecified (spec);
9317 }
9318
9319 functionConstraint_free (spec->info->fcn->postconditions);
9320 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9321 def->info->fcn->postconditions = functionConstraint_undefined;
ba45e1e4 9322 }
9323 }
9324 }
9325}
9326
616915dd 9327/*
9328** modifies spec to reflect def, reports any inconsistencies
9329*/
9330
9331void
9332uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9333{
9334 llassert (uentry_isValid (spec));
9335 llassert (uentry_isValid (def));
9336 llassert (cstring_equal (spec->uname, def->uname));
efd360a3 9337
9338 if (uentry_isFunction (def))
9339 {
9340 if (uentry_isConstant (spec))
9341 {
9342 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9343 uentry_makeConstantFunction (spec);
9344 }
9345 else
9346 {
9347 uentry_convertVarFunction (spec);
9348 }
9349
9350 llassert (uentry_isFunction (spec));
9351 }
28bf4b0b 9352
9353 DPRINTF (("Merge entries: %s / %s",
9354 uentry_unparseFull (spec),
9355 uentry_unparseFull (def)));
616915dd 9356
ba45e1e4 9357 uentry_mergeConstraints (spec, def);
9358
616915dd 9359 uentry_checkConformance (spec, def, TRUE,
9360 context_getFlag (FLG_NEEDSPEC));
9361
28bf4b0b 9362 DPRINTF (("Merge entries after conform: %s / %s",
9363 uentry_unparseFull (spec),
9364 uentry_unparseFull (def)));
9365
616915dd 9366 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9367
9368 /*
9369 ** okay, declarations conform. Propagate extra information.
9370 */
9371
9372 uentry_setDefined (spec, uentry_whereDefined (def));
9373 uentry_setDeclared (spec, uentry_whereDeclared (def));
9374
9375 if (uentry_isStatic (def))
9376 {
9377 if (optgenerror
9378 (FLG_INCONDEFS,
9379 message ("%s %q specified, but declared as static",
9380 ekind_capName (def->ukind),
9381 uentry_getName (def)),
9382 uentry_whereDeclared (def)))
9383 {
9384 uentry_showWhereSpecified (spec);
9385 }
9386 }
9387 else
9388 {
9389 spec->storageclass = def->storageclass;
9390 }
9391
9392 sRef_storeState (spec->sref);
9393
9394 spec->used = def->used || spec->used;
9395 spec->hasNameError |= def->hasNameError;
9396
9397 uentry_free (def);
9398
9399 if (!spec->hasNameError)
9400 {
9401 uentry_checkName (spec);
9402 }
9403 else
9404 {
9405 ;
9406 }
9407}
9408
9409/*
9410** Can't generate function redeclaration errors when the
9411** entries are merged, since we don't yet know if its the
9412** definition of the function.
9413*/
9414
9415void
9416uentry_clearDecl (void)
9417{
9418 posRedeclared = uentry_undefined;
9419 fileloc_free (posLoc);
9420 posLoc = fileloc_undefined;
9421}
9422
9423void
9424uentry_checkDecl (void)
9425{
f0171cff 9426 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
616915dd 9427 {
9428 llassert (fileloc_isDefined (posLoc));
9429
9430 if (uentry_isCodeDefined (posRedeclared))
9431 {
9432 if (optgenerror (FLG_REDECL,
9433 message ("%s %q declared after definition",
9434 ekind_capName (posRedeclared->ukind),
9435 uentry_getName (posRedeclared)),
9436 posLoc))
9437 {
9438 llgenindentmsg (message ("Definition of %q",
9439 uentry_getName (posRedeclared)),
9440 posRedeclared->whereDeclared);
9441 }
9442 }
9443 else
9444 {
9445 if (optgenerror (FLG_REDECL,
9446 message ("%s %q declared more than once",
9447 ekind_capName (posRedeclared->ukind),
9448 uentry_getName (posRedeclared)),
9449 posLoc))
9450 {
9451 llgenindentmsg (message ("Previous declaration of %q",
9452 uentry_getName (posRedeclared)),
9453 posRedeclared->whereDeclared);
9454 }
9455 }
9456 }
9457
9458 fileloc_free (posLoc);
9459 posLoc = fileloc_undefined;
9460 posRedeclared = uentry_undefined;
9461}
9462
9463/*
9464** Redefinition of old as unew.
9465** modifies old to reflect unew, reports any inconsistencies
9466*/
9467
9468void
9469uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9470{
d89a0c94 9471 fileloc olddef = uentry_whereDeclared (old);
616915dd 9472 fileloc unewdef = uentry_whereDeclared (unew);
9473 bool mustConform;
9474 bool wasForward;
28bf4b0b 9475
9476 DPRINTF (("uentry merge: %s / %s",
9477 uentry_unparseFull (old),
9478 uentry_unparseFull (unew)));
616915dd 9479
616915dd 9480 wasForward =
9481 fileloc_isUndefined (olddef)
efd360a3 9482 && fileloc_isDefined (uentry_whereDefined (old))
9483 && !uentry_isExpandedMacro (old);
616915dd 9484
9485 if (!context_getFlag (FLG_INCONDEFSLIB)
9486 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9487 {
9488 mustConform = FALSE;
9489 }
9490 else
9491 {
9492 mustConform = TRUE;
9493 }
9494
9495 llassert (uentry_isValid (old));
9496 llassert (uentry_isValid (unew));
9497 llassert (cstring_equal (old->uname, unew->uname));
9498
efd360a3 9499 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9500 {
9501 if (uentry_isConstant (old))
9502 {
9503 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9504 uentry_makeConstantFunction (old);
9505 }
9506 else
9507 {
9508 uentry_convertVarFunction (old);
9509 }
9510
9511 llassert (uentry_isFunction (old));
9512 }
9513
9514 DPRINTF (("uentry merge: %s / %s",
9515 uentry_unparseFull (old),
9516 uentry_unparseFull (unew)));
9517
9518 if (uentry_isExtern (unew))
9519 {
9520 uentry_setUsed (old, unewdef);
9521 }
9522
616915dd 9523 /*
9524 ** should check old one was extern!
9525 */
9526
9527 if (uentry_isStatic (old))
9528 {
9529 if (!(uentry_isStatic (unew)))
9530 {
9531 if (optgenerror
9532 (FLG_SHADOW,
9533 message ("%s %q shadows static declaration",
9534 ekind_capName (unew->ukind),
9535 uentry_getName (unew)),
9536 unewdef))
9537 {
9538 uentry_showWhereLast (old);
9539 }
9540 }
9541 else
9542 {
9543 uentry_setDeclDef (old, unewdef);
9544 }
9545 }
9546 else if (uentry_isStatic (unew))
9547 {
9548 uentry_setDeclDef (old, unewdef);
9549 }
9550 else if (uentry_isExtern (old))
9551 {
9552 uentry_setDeclared (old, unewdef);
9553 }
9554 else
9555 {
d89a0c94 9556 if (!uentry_isExtern (unew)
9557 && !uentry_isForward (old)
616915dd 9558 && !fileloc_equal (olddef, unewdef)
9559 && !fileloc_isUndefined (olddef)
9560 && !fileloc_isUndefined (unewdef)
9561 && !fileloc_isBuiltin (olddef)
9562 && !fileloc_isBuiltin (unewdef)
9563 && !uentry_isYield (old)
9564 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9565 {
9566 if (uentry_isVariable (old) || uentry_isVariable (unew))
9567 {
9568 ; /* will report redeclaration error later */
9569 }
9570 else
9571 {
9572 if (fileloc_isDefined (uentry_whereDefined (old)))
9573 {
9574 if (optgenerror
9575 (FLG_REDEF,
9576 message ("%s %q defined more than once",
9577 ekind_capName (unew->ukind),
9578 uentry_getName (unew)),
9579 uentry_whereLast (unew)))
9580 {
9581 llgenindentmsg
9582 (message ("Previous definition of %q",
9583 uentry_getName (old)),
9584 uentry_whereLast (old));
9585 }
9586 /*
9587 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9588 {
efd360a3 9589 uentry_updateInto (old, unew);
616915dd 9590 old->sref = sRef_saveCopy (old->sref);
9591 }
9592 */
9593 }
9594 }
9595 }
9596 else
9597 {
9598 if (fileloc_isLib (olddef)
9599 || fileloc_isUndefined (olddef)
9600 || fileloc_isImport (olddef))
9601 {
9602 if (uentry_isExtern (unew))
9603 {
9604 if (uentry_isExtern (old)
9605 || (fileloc_isDefined (uentry_whereDeclared (old))
9606 && (!fileloc_equal (uentry_whereDeclared (old),
9607 uentry_whereDefined (old)))))
9608 {
9609 if (optgenerror
9610 (FLG_REDECL,
9611 message ("%s %q declared more than once",
9612 ekind_capName (unew->ukind),
9613 uentry_getName (unew)),
9614 unew->whereDeclared))
9615 {
9616 llgenindentmsg
9617 (message ("Previous declaration of %q",
9618 uentry_getName (old)),
9619 old->whereDeclared);
9620 }
9621 }
9622
9623 uentry_setExtern (old);
9624 }
9625 else
9626 {
d89a0c94 9627 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
616915dd 9628 }
9629 }
9630 }
9631 }
9632
efd360a3 9633 DPRINTF (("uentry merge: %s / %s",
9634 uentry_unparseFull (old),
9635 uentry_unparseFull (unew)));
ba45e1e4 9636
efd360a3 9637 uentry_mergeConstraints (old, unew);
d89a0c94 9638 DPRINTF (("uentry merge: %s / %s",
9639 uentry_unparseFull (old),
9640 uentry_unparseFull (unew)));
9641
616915dd 9642 uentry_checkConformance (old, unew, mustConform, FALSE);
d89a0c94 9643 DPRINTF (("uentry merge: %s / %s",
9644 uentry_unparseFull (old),
9645 uentry_unparseFull (unew)));
616915dd 9646
9647 old->used = old->used || unew->used;
9648 old->uses = filelocList_append (old->uses, unew->uses);
9649 unew->uses = filelocList_undefined;
9650
9651 sRef_storeState (old->sref);
9652 sRef_storeState (unew->sref);
9653
9654 if (wasForward)
9655 {
9656 old->whereDefined = fileloc_update (old->whereDefined,
9657 fileloc_undefined);
9658 }
9659
d89a0c94 9660 DPRINTF (("here: %s", uentry_unparseFull (old)));
9661
616915dd 9662 /*
9663 ** No redeclaration errors for functions here, since we
9664 ** don't know if this is the definition of the function.
9665 */
9666
9667 if (fileloc_isUser (old->whereDeclared)
9668 && fileloc_isUser (unew->whereDeclared)
9669 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9670 && !fileloc_isDefined (unew->whereDefined))
9671 {
9672 if (uentry_isFunction (old))
9673 {
9674 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9675 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9676 }
9677 else
9678 {
9679 if (optgenerror (FLG_REDECL,
9680 message ("%s %q declared more than once",
9681 ekind_capName (unew->ukind),
9682 uentry_getName (unew)),
9683 unew->whereDeclared))
9684 {
9685 llgenindentmsg (message ("Previous declaration of %q",
9686 uentry_getName (old)),
9687 old->whereDeclared);
9688 }
9689 }
9690 }
9691
9692 if (fileloc_isUndefined (old->whereDefined))
9693 {
9694 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9695 }
9696 else
9697 {
9698 if (!context_processingMacros ()
9699 && fileloc_isUser (old->whereDefined)
9700 && fileloc_isUser (unew->whereDefined)
9701 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9702 {
9703 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9704 {
9705 if (uentry_isVariable (unew)
9706 && uentry_isExtern (unew))
9707 {
9708 if (optgenerror (FLG_REDECL,
9709 message ("%s %q declared after definition",
9710 ekind_capName (unew->ukind),
9711 uentry_getName (unew)),
9712 unew->whereDeclared))
9713 {
9714 llgenindentmsg (message ("Definition of %q",
9715 uentry_getName (old)),
9716 old->whereDefined);
9717 }
9718 }
9719 else
9720 {
9721 if (optgenerror (FLG_REDEF,
9722 message ("%s %q redefined",
9723 ekind_capName (unew->ukind),
9724 uentry_getName (unew)),
9725 unew->whereDefined))
9726 {
9727 llgenindentmsg (message ("Previous definition of %q",
9728 uentry_getName (old)),
9729 old->whereDefined);
9730 }
9731 }
9732 }
9733 }
9734 }
9735
9736 if (uentry_isExternal (unew))
9737 {
9738 old->whereDefined = fileloc_createExternal ();
9739 }
9740
9741 if (unew->hasNameError)
9742 {
9743 old->hasNameError = TRUE;
9744 }
9745
9746 uentry_free (unew);
9747
9748 if (!old->hasNameError)
9749 {
9750 uentry_checkName (old);
9751 }
9752
d89a0c94 9753 DPRINTF (("After: %s", uentry_unparseFull (old)));
616915dd 9754 llassert (!ctype_isUndefined (old->utype));
9755}
9756
9757void
9758uentry_copyState (uentry res, uentry other)
9759{
9760 llassert (uentry_isValid (res));
9761 llassert (uentry_isValid (other));
9762
9763 res->used = other->used;
9764
9765 res->info->var->kind = other->info->var->kind;
9766 res->info->var->defstate = other->info->var->defstate;
9767 res->info->var->nullstate = other->info->var->nullstate;
9768 res->info->var->checked = other->info->var->checked;
9769
9770 sRef_copyState (res->sref, other->sref);
9771}
9772
9773bool
9774uentry_sameKind (uentry u1, uentry u2)
9775{
9776 if (uentry_isValid (u1) && uentry_isValid (u2))
9777 {
9778 if (uentry_isVar (u1) && uentry_isVar (u2))
9779 {
9780 ctype c1 = u1->utype;
9781 ctype c2 = u2->utype;
9782
9783 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9784
9785 /*
9786 ** both functions, or both not functions
9787 */
9788
9789 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9790 }
9791 else
9792 {
9793 return ((u1->ukind == u2->ukind));
9794 }
9795 }
9796
9797 return FALSE;
9798}
9799
efd360a3 9800static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
616915dd 9801{
efd360a3 9802 ekind okind = unew->ukind;
616915dd 9803 llassert (uentry_isValid (unew));
9804 llassert (uentry_isValid (old));
9805
d89a0c94 9806 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9807
616915dd 9808 unew->ukind = old->ukind;
efd360a3 9809 llassert (cstring_equal (unew->uname, old->uname));
616915dd 9810 unew->utype = old->utype;
9811
efd360a3 9812 if (fileloc_isDefined (unew->whereSpecified)
9813 && !fileloc_isDefined (old->whereSpecified))
9814 {
9815 ; /* Keep the old value */
9816 }
9817 else
9818 {
9819 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9820 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9821 }
9822
9823 if (fileloc_isDefined (unew->whereDefined)
9824 && !fileloc_isDefined (old->whereDefined))
9825 {
9826 ; /* Keep the old value */
9827 }
9828 else
9829 {
9830 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9831 unew->whereDefined = fileloc_copy (old->whereDefined);
9832 }
9833
9834 if (fileloc_isDefined (unew->whereDeclared)
9835 && !fileloc_isDefined (old->whereDeclared))
9836 {
9837 ; /* Keep the old value */
9838 }
9839 else
9840 {
9841 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9842 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9843 }
616915dd 9844
d89a0c94 9845 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9846
616915dd 9847 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9848 unew->used = old->used;
9849 unew->lset = FALSE;
9850 unew->isPrivate = old->isPrivate;
9851 unew->hasNameError = old->hasNameError;
efd360a3 9852 unew->uses = filelocList_append (unew->uses, old->uses);
9853 old->uses = filelocList_undefined;
616915dd 9854
9855 unew->storageclass = old->storageclass;
efd360a3 9856 uinfo_free (unew->info, okind);
616915dd 9857 unew->info = uinfo_copy (old->info, old->ukind);
9858}
9859
9860
9861uentry
9862uentry_copy (uentry e)
9863{
9864 if (uentry_isValid (e))
9865 {
9866 uentry enew = uentry_alloc ();
9867 DPRINTF (("copy: %s", uentry_unparseFull (e)));
efd360a3 9868 enew->ukind = e->ukind;
9869 enew->uname = cstring_copy (e->uname);
9870 enew->utype = e->utype;
9871
9872 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9873 enew->whereDefined = fileloc_copy (e->whereDefined);
9874 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9875
9876 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9877 enew->used = e->used;
9878 enew->lset = FALSE;
9879 enew->isPrivate = e->isPrivate;
9880 enew->hasNameError = e->hasNameError;
9881 enew->uses = filelocList_undefined;
9882
9883 enew->storageclass = e->storageclass;
9884 enew->info = uinfo_copy (e->info, e->ukind);
9885 enew->warn = warnClause_copy (e->warn);
9886
616915dd 9887 DPRINTF (("Here we are..."));
9888 DPRINTF (("original: %s", uentry_unparseFull (e)));
9889 DPRINTF (("copy: %s", uentry_unparse (enew)));
9890 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9891 return enew;
9892 }
9893 else
9894 {
9895 return uentry_undefined;
9896 }
9897}
9898
9899void
9900uentry_setState (uentry res, uentry other)
9901{
9902 llassert (uentry_isValid (res));
9903 llassert (uentry_isValid (other));
9904
9905 llassert (res->ukind == other->ukind);
9906 llassert (res->ukind == KVAR);
9907
9908 res->sref = sRef_saveCopy (other->sref);
9909 res->used = other->used;
9910 filelocList_free (res->uses);
9911 res->uses = other->uses;
9912 other->uses = filelocList_undefined;
9913 res->lset = other->lset;
9914}
9915
9916void
9917uentry_mergeUses (uentry res, uentry other)
9918{
9919 llassert (uentry_isValid (res));
9920 llassert (uentry_isValid (other));
9921
9922 res->used = other->used || res->used;
9923 res->lset = other->lset || res->lset;
9924 res->uses = filelocList_append (res->uses, other->uses);
9925 other->uses = filelocList_undefined;
9926}
9927
9928
9929/*
9930** This is a really ugly routine.
9931**
9932** gack...fix this one day.
9933*/
9934
9935/*
9936** flip == TRUE
9937** >> res is the false branch, other is the true branch (or continuation)
9938** flip == FALSE
9939** >> res is the true branch, other is the false branch (or continutation)
9940**
9941** opt == TRUE if,
9942**
9943** <other>
9944** if <res> ;
9945**
9946** References not effected by res are propagated from other.
9947*/
9948
9949static void
9950 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9951 bool flip, clause cl, fileloc loc)
9952{
9953 if (optgenerror
9954 (FLG_BRANCHSTATE,
9955 message ("%s %q is %s %s, but %s %s.",
9956 ekind_capName (res->ukind), uentry_getName (res),
9957 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9958 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9959 loc))
9960 {
9961 if (sRef_isDead (res->sref))
9962 {
9963 sRef_showStateInfo (res->sref);
9964 }
9965 else if (sRef_isKept (res->sref))
9966 {
9967 sRef_showAliasInfo (res->sref);
9968 }
9969 else /* dependent */
9970 {
9971 sRef_showAliasInfo (res->sref);
9972 sRef_showAliasInfo (other->sref);
9973 }
9974
9975 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9976 }
9977}
9978
60868d40 9979static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
616915dd 9980{
9981 alkind rk = sRef_getAliasKind (rs);
9982 alkind ok = sRef_getAliasKind (os);
9983
9984 if (alkind_isError (rk) || alkind_isError (ok))
9985 {
9986 return FALSE;
9987 }
9988 else
9989 {
9990 return ((sRef_isDead (rs)
9991 || (alkind_isKept (rk) && !alkind_isKept (ok))
9992 || (alkind_isDependent (rk)
9993 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9994 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9995 }
9996}
9997
9998static void
9999 branchStateAltError (/*@notnull@*/ uentry res,
10000 /*@notnull@*/ uentry other, bool flip,
10001 clause cl, fileloc loc)
10002{
10003 if (optgenerror
10004 (FLG_BRANCHSTATE,
10005 message ("%s %q is %s %s, but %s %s.",
10006 ekind_capName (res->ukind), uentry_getName (res),
10007 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10008 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10009 loc))
10010 {
10011 if (sRef_isDead (other->sref))
10012 {
10013 sRef_showStateInfo (other->sref);
10014 }
10015 else /* kept */
10016 {
10017 sRef_showAliasInfo (other->sref);
10018 }
10019
10020 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10021 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10022
10023 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10024 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10025 }
10026}
10027
28bf4b0b 10028/*
10029** A reference is relevant for certain checks, only if it
10030** is not definitely null on this path (but not declared
10031** to always be null.)
10032*/
10033
10034static bool uentry_relevantReference (sRef sr, bool flip)
616915dd 10035{
28bf4b0b 10036 if (sRef_isKept (sr) || sRef_isDependent (sr))
10037 {
10038 return FALSE;
10039 }
10040 else
10041 {
10042 if (flip)
10043 {
10044 return !sRef_definitelyNullContext (sr);
10045 }
10046 else
10047 {
10048 return !sRef_definitelyNullAltContext (sr);
10049 }
10050 }
616915dd 10051}
616915dd 10052
28bf4b0b 10053static void
10054uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
10055 bool mustReturn, bool flip, bool opt,
10056 clause cl)
10057{
60868d40 10058 sRef rs = res->sref;
10059 sRef os = other->sref;
10060
28bf4b0b 10061 DPRINTF (("Merge alias states: %s / %s",
10062 uentry_unparseFull (res),
10063 uentry_unparseFull (other)));
616915dd 10064
60868d40 10065 if (sRef_isValid (rs))
616915dd 10066 {
10067 if (!mustReturn)
10068 {
60868d40 10069 if (uentry_incompatibleMemoryStates (rs, os))
616915dd 10070 {
60868d40 10071 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10072 sRef_unparseFull (rs), sRef_unparseFull (os)));
28bf4b0b 10073
60868d40 10074 if (sRef_isThroughArrayFetch (rs)
616915dd 10075 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10076 {
60868d40 10077 if (sRef_isKept (rs) || sRef_isKept (os))
616915dd 10078 {
60868d40 10079 sRef_maybeKill (rs, loc);
616915dd 10080 }
60868d40 10081 else if (sRef_isPossiblyDead (os))
616915dd 10082 {
60868d40 10083 sRef_maybeKill (rs, loc);
616915dd 10084 }
10085 else
10086 {
10087 ;
10088 }
10089 }
10090 else
10091 {
60868d40 10092 if (uentry_relevantReference (os, flip))
616915dd 10093 {
60868d40 10094 if (sRef_isLocalParamVar (rs)
10095 && (sRef_isLocalState (os)
10096 || sRef_isDependent (os)))
616915dd 10097 {
60868d40 10098 if (sRef_isDependent (rs))
616915dd 10099 {
60868d40 10100 sRef_setDependent (os, loc);
616915dd 10101 }
10102 else
10103 {
60868d40 10104 sRef_setDefState (rs, SS_UNUSEABLE, loc);
616915dd 10105 }
10106 }
10107 else
10108 {
10109 branchStateError (res, other, flip, cl, loc);
10110 }
10111 }
10112 }
10113
60868d40 10114 if (sRef_isKept (rs))
616915dd 10115 {
60868d40 10116 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10117 sRef_setKept (os, loc);
616915dd 10118 }
10119 }
10120 else
10121 {
60868d40 10122 if (uentry_incompatibleMemoryStates (os, rs))
616915dd 10123 {
60868d40 10124 if (uentry_relevantReference (rs, !flip))
616915dd 10125 {
60868d40 10126 if (sRef_isLocalParamVar (rs)
10127 && (sRef_isDependent (rs)
10128 || sRef_isLocalState (rs)))
616915dd 10129 {
60868d40 10130 if (sRef_isDependent (os))
616915dd 10131 {
60868d40 10132 sRef_setDependent (rs, loc);
616915dd 10133 }
10134 else
10135 {
60868d40 10136 sRef_setDefState (rs, SS_UNUSEABLE, loc);
616915dd 10137 }
10138 }
10139 else
10140 {
60868d40 10141 if (sRef_isParam (os))
616915dd 10142 {
10143 /*
10144 ** If the local variable associated
10145 ** with the param has the correct state,
10146 ** its okay.
10147 ** (e.g., free (s); s = new(); ...
10148 */
28bf4b0b 10149
616915dd 10150 uentry uvar = usymtab_lookupSafe (other->uname);
28bf4b0b 10151
616915dd 10152 if (uentry_isValid (uvar)
60868d40 10153 && ((sRef_isDead (os)
616915dd 10154 && sRef_isOnly (uvar->sref))
60868d40 10155 || (sRef_isDependent (os)
616915dd 10156 && sRef_isOwned (uvar->sref))))
10157 {
10158 /* no error */
10159 }
10160 else
10161 {
10162 branchStateAltError (res, other,
10163 flip, cl, loc);
10164 }
10165 }
10166 else
10167 {
28bf4b0b 10168 DPRINTF (("Here: %s / %s",
10169 uentry_unparseFull (res),
10170 uentry_unparseFull (other)));
10171
616915dd 10172 branchStateAltError (res, other,
10173 flip, cl, loc);
10174 }
10175 }
10176 }
10177 }
28bf4b0b 10178
60868d40 10179 if (sRef_isKept (os))
616915dd 10180 {
60868d40 10181 sRef_setKept (rs, loc);
616915dd 10182 }
10183 }
10184
10185 if (opt)
10186 {
10187 DPRINTF (("Merge opt..."));
60868d40 10188 sRef_mergeOptState (rs, os, cl, loc);
616915dd 10189 DPRINTF (("Done!"));
10190 }
10191 else
10192 {
60868d40 10193 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10194 sRef_mergeState (rs, os, cl, loc);
10195 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
616915dd 10196 }
10197 }
10198 else
10199 {
60868d40 10200 if (sRef_isModified (os))
616915dd 10201 {
60868d40 10202 sRef_setModified (rs);
616915dd 10203 }
10204 }
28bf4b0b 10205 }
60868d40 10206
10207 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
28bf4b0b 10208}
616915dd 10209
28bf4b0b 10210static void
b7e84605 10211uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
28bf4b0b 10212{
10213 valueTable rvalues;
10214 valueTable ovalues;
10215
10216 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10217
b7e84605 10218 if (mustReturn)
10219 {
10220 return;
10221 }
10222 /* flip? */
10223
28bf4b0b 10224 rvalues = sRef_getValueTable (res->sref);
10225 ovalues = sRef_getValueTable (other->sref);
10226
10227 if (valueTable_isUndefined (ovalues))
10228 {
10229 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10230 ;
10231 }
10232 else if (valueTable_isUndefined (rvalues))
10233 {
10234 /*
10235 ** Copy values from other
10236 */
10237
10238 /*@i$@#@*/
10239 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10240 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10241 ;
10242 }
10243 else
10244 {
10245 valueTable_elements (ovalues, fkey, fval) {
10246 stateValue tval;
10247 metaStateInfo minfo;
10248 stateCombinationTable sctable;
10249 cstring msg;
10250 int nval;
10251
10252 tval = valueTable_lookup (rvalues, fkey);
10253
10254 DPRINTF (("Merge value: %s / %s X %s", fkey,
10255 stateValue_unparse (fval), stateValue_unparse (tval)));
10256
10257 minfo = context_lookupMetaStateInfo (fkey);
10258 llassert (stateValue_isDefined (tval));
10259
10260 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10261 {
10262 DPRINTF (("Cannot find meta state for: %s", fkey));
10263 BADBRANCH;
10264 }
10265 else
10266 {
10267 llassert (metaStateInfo_isDefined (minfo));
10268
10269 if (stateValue_isError (fval)
10270 || sRef_definitelyNullContext (res->sref))
10271 {
10272 sRef_setMetaStateValueComplete (res->sref,
10273 fkey, stateValue_getValue (fval),
b7e84605 10274 stateValue_getLoc (fval));
28bf4b0b 10275 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10276 }
10277 else if (stateValue_isError (tval)
10278 || sRef_definitelyNullAltContext (other->sref))
10279 {
10280 DPRINTF (("Other branch is definitely null!"));
10281 }
b7e84605 10282 else if (sRef_isStateUndefined (res->sref)
10283 || sRef_isDead (res->sref))
10284 {
10285 ; /* Combination state doesn't matter if it is undefined or dead */
10286 }
28bf4b0b 10287 else
10288 {
10289 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10290 metaStateInfo_unparse (minfo),
10291 stateValue_unparse (fval),
10292 stateValue_unparse (tval)));
10293
10294 DPRINTF (("state values: %d / %d",
10295 stateValue_getValue (fval), stateValue_getValue (tval)));
10296
10297 sctable = metaStateInfo_getMergeTable (minfo);
10298
10299 DPRINTF (("Merge table: %s",
10300 stateCombinationTable_unparse (sctable)));
10301
10302 msg = cstring_undefined;
10303
10304 nval = stateCombinationTable_lookup (sctable,
10305 stateValue_getValue (fval),
10306 stateValue_getValue (tval),
10307 &msg);
10308
10309 DPRINTF (("nval: %d / %d / %d", nval,
10310 stateValue_getValue (fval), stateValue_getValue (tval)));
10311
b7e84605 10312 if (nval == stateValue_error)
28bf4b0b 10313 {
10314 /*@i32 print extra info for assignments@*/
10315
10316 if (uentry_isGlobalMarker (res))
10317 {
10318 if (optgenerror
10319 (FLG_STATEMERGE,
10320 message
b7e84605 10321 ("Control branches merge with incompatible global states (%s and %s)%q",
28bf4b0b 10322 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10323 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
b7e84605 10324 cstring_isDefined (msg)
10325 ? message (": %s", msg) : cstring_undefined),
28bf4b0b 10326 loc))
10327 {
10328 sRef_showMetaStateInfo (res->sref, fkey);
10329 sRef_showMetaStateInfo (other->sref, fkey);
10330 }
10331 }
10332 else
10333 {
10334 if (optgenerror
10335 (FLG_STATEMERGE,
10336 message
b7e84605 10337 ("Control branches merge with incompatible states for %q (%s and %s)%q",
28bf4b0b 10338 uentry_getName (res),
10339 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10340 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
b7e84605 10341 cstring_isDefined (msg)
10342 ? message (": %s", msg) : cstring_undefined),
28bf4b0b 10343 loc))
10344 {
10345 sRef_showMetaStateInfo (res->sref, fkey);
10346 sRef_showMetaStateInfo (other->sref, fkey);
10347 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10348 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10349 DPRINTF (("Null: %s / %s",
10350 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10351 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10352
10353 }
10354 }
10355 }
10356
10357 if (nval == stateValue_getValue (fval)
10358 && nval != stateValue_getValue (tval))
10359 {
10360 loc = stateValue_getLoc (fval);
10361 }
10362 else if (nval == stateValue_getValue (tval)
10363 && nval != stateValue_getValue (fval))
10364 {
10365 loc = stateValue_getLoc (tval);
10366 }
10367 else
10368 {
10369 ;
10370 }
10371
10372 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10373 && nval == stateValue_getValue (fval)
10374 && nval == stateValue_getValue (tval))
10375 {
10376 ;
10377 }
10378 else
10379 {
10380 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10381 }
10382 }
10383 }
10384 } end_valueTable_elements ;
10385 }
10386}
10387
10388
10389static void
10390uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10391 bool flip, clause cl)
10392{
10393 if (cl == DOWHILECLAUSE)
10394 {
10395 res->used = other->used || res->used;
10396 res->lset = other->lset || res->lset;
10397 res->uses = filelocList_append (res->uses, other->uses);
10398 other->uses = filelocList_undefined;
10399 }
10400 else
10401 {
10402 if (sRef_isMacroParamRef (res->sref)
10403 && !uentry_isSefParam (other)
10404 && !uentry_isSefParam (res))
616915dd 10405 {
28bf4b0b 10406 bool hasError = FALSE;
10407
10408 if (bool_equal (res->used, other->used))
616915dd 10409 {
28bf4b0b 10410 res->used = other->used;
10411 }
10412 else
10413 {
10414 if (other->used && !flip)
616915dd 10415 {
28bf4b0b 10416 hasError =
10417 optgenerror
10418 (FLG_MACROPARAMS,
10419 message ("Macro parameter %q used in true clause, "
10420 "but not in false clause",
10421 uentry_getName (res)),
10422 uentry_whereDeclared (res));
616915dd 10423 }
10424 else
28bf4b0b 10425 {
10426 hasError =
10427 optgenerror
10428 (FLG_MACROPARAMS,
10429 message ("Macro parameter %q used in false clause, "
10430 "but not in true clause",
10431 uentry_getName (res)),
10432 uentry_whereDeclared (res));
10433 }
10434 res->used = TRUE;
10435
10436 if (hasError)
616915dd 10437 {
28bf4b0b 10438 /* make it sef now, prevent more errors */
10439 res->info->var->kind = VKREFSEFPARAM;
616915dd 10440 }
10441 }
28bf4b0b 10442 }
10443 else
10444 {
10445 res->used = other->used || res->used;
10446 res->lset = other->lset || res->lset;
10447 res->uses = filelocList_append (res->uses, other->uses);
10448 other->uses = filelocList_undefined;
616915dd 10449 }
10450 }
10451}
10452
28bf4b0b 10453void
10454uentry_mergeState (uentry res, uentry other, fileloc loc,
10455 bool mustReturn, bool flip, bool opt,
10456 clause cl)
10457{
10458 llassert (uentry_isValid (res));
10459 llassert (uentry_isValid (other));
10460
10461 llassert (res->ukind == other->ukind);
10462 llassert (res->ukind == KVAR);
10463
10464 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10465 uentry_unparseFull (other)));
10466
10467 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
b7e84605 10468 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
28bf4b0b 10469 uentry_mergeSetStates (res, other, loc, flip, cl);
10470}
10471
616915dd 10472void uentry_setUsed (uentry e, fileloc loc)
10473{
10474 static bool firstTime = TRUE;
10475 static bool showUses = FALSE;
10476 static bool exportLocal = FALSE;
10477
28bf4b0b 10478 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10479
616915dd 10480 if (firstTime)
10481 {
10482 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10483
10484 showUses = context_getFlag (FLG_SHOWUSES);
10485 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10486
10487 firstTime = FALSE;
10488 }
10489
10490 if (uentry_isValid (e))
10491 {
10492 int dp;
28bf4b0b 10493
10494 if (warnClause_isDefined (e->warn))
10495 {
10496 flagSpec flg = warnClause_getFlag (e->warn);
10497 cstring msg;
10498
10499 if (warnClause_hasMessage (e->warn))
10500 {
10501 msg = cstring_copy (warnClause_getMessage (e->warn));
10502 }
10503 else
10504 {
10505 msg = message ("Use of possibly dangerous %s",
10506 uentry_ekindNameLC (e));
10507 }
10508
10509 vfsgenerror (flg,
10510 message ("%q: %q", msg, uentry_getName (e)),
10511 loc);
10512 }
10513
616915dd 10514 if (sRef_isMacroParamRef (e->sref))
10515 {
10516 if (uentry_isYield (e) || uentry_isSefParam (e))
10517 {
10518 ;
10519 }
10520 else
10521 {
10522 if (context_inConditional ())
10523 {
10524 if (optgenerror
10525 (FLG_MACROPARAMS,
10526 message ("Macro parameter %q used in conditionally "
10527 "executed code (may or may not be "
10528 "evaluated exactly once)",
10529 uentry_getName (e)),
10530 loc))
10531 {
10532 e->info->var->kind = VKREFSEFPARAM;
10533 }
10534 }
10535 else
10536 {
10537 if ((e)->used)
10538 {
10539 if (optgenerror
10540 (FLG_MACROPARAMS,
10541 message ("Macro parameter %q used more than once",
10542 uentry_getName (e)),
10543 uentry_whereDeclared (e)))
10544 {
10545 e->info->var->kind = VKREFSEFPARAM;
10546 }
10547 }
10548 }
10549 }
10550 }
10551
10552 if ((dp = uentry_directParamNo (e)) >= 0)
10553 {
10554 uentry_setUsed (usymtab_getParam (dp), loc);
10555 }
10556
10557 e->used = TRUE;
28bf4b0b 10558
616915dd 10559 if (!sRef_isLocalVar (e->sref))
10560 {
10561 if (showUses)
10562 {
10563 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10564 }
10565 else
10566 {
10567 if (exportLocal)
10568 {
10569 if (context_inMacro ())
10570 {
10571 e->uses = filelocList_addUndefined (e->uses);
10572 }
10573 else
10574 {
10575 e->uses = filelocList_addDifferentFile
10576 (e->uses,
10577 uentry_whereDeclared (e),
10578 loc);
10579 }
10580 }
10581 }
10582 }
10583 }
10584}
10585
10586bool uentry_isReturned (uentry u)
10587{
10588 return (uentry_isValid (u) && uentry_isVar (u)
10589 && (u->info->var->kind == VKRETPARAM
10590 || u->info->var->kind == VKSEFRETPARAM));
10591}
10592
10593/*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10594{
10595 llassert (uentry_isRealFunction (u));
10596
28bf4b0b 10597 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
616915dd 10598 {
28bf4b0b 10599 stateClauseList clauses = uentry_getStateClauseList (u);
10600 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
616915dd 10601
28bf4b0b 10602 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
616915dd 10603 sRef_setAllocated (res, g_currentloc);
10604
28bf4b0b 10605 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10606 stateClauseList_unparse (clauses)));
616915dd 10607
ccf0a4a8 10608 /*
10609 ** This should be in exprNode_reflectEnsuresClause
10610 */
10611
28bf4b0b 10612 stateClauseList_postElements (clauses, cl)
10613 {
10614 if (!stateClause_isGlobal (cl))
616915dd 10615 {
28bf4b0b 10616 sRefSet refs = stateClause_getRefs (cl);
10617 sRefMod modf = stateClause_getEffectFunction (cl);
10618
10619 sRefSet_elements (refs, el)
616915dd 10620 {
28bf4b0b 10621 sRef base = sRef_getRootBase (el);
10622
10623 if (sRef_isResult (base))
616915dd 10624 {
28bf4b0b 10625 if (modf != NULL)
10626 {
10627 sRef sr = sRef_fixBase (el, res);
10628 modf (sr, g_currentloc);
10629 }
616915dd 10630 }
28bf4b0b 10631 else
10632 {
10633 ;
10634 }
10635 } end_sRefSet_elements ;
10636 }
10637 } end_stateClauseList_postElements ;
ccf0a4a8 10638
616915dd 10639 return res;
10640 }
10641 else
10642 {
10643 uentryList params;
10644 alkind ak;
10645 sRefSet prefs = sRefSet_new ();
10646 sRef res = sRef_undefined;
10647 int paramno = 0;
10648
10649 params = uentry_getParams (u);
10650
10651 uentryList_elements (params, current)
10652 {
10653 if (uentry_isReturned (current))
10654 {
10655 if (exprNodeList_size (args) >= paramno)
10656 {
10657 exprNode ecur = exprNodeList_nth (args, paramno);
10658 sRef tref = exprNode_getSref (ecur);
10659
28bf4b0b 10660 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10661
616915dd 10662 if (sRef_isValid (tref))
10663 {
10664 sRef tcref = sRef_copy (tref);
10665
28bf4b0b 10666 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10667
616915dd 10668 if (sRef_isDead (tcref))
10669 {
10670 sRef_setDefined (tcref, g_currentloc);
10671 sRef_setOnly (tcref, g_currentloc);
10672 }
10673
10674 if (sRef_isRefCounted (tcref))
10675 {
10676 /* could be a new ref now (but only if its returned) */
10677 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10678 }
10679
10680 sRef_makeSafe (tcref);
616915dd 10681 prefs = sRefSet_insert (prefs, tcref);
10682 }
10683 }
10684 }
10685
10686 paramno++;
10687 } end_uentryList_elements ;
10688
10689 if (sRefSet_size (prefs) > 0)
10690 {
10691 nstate n = sRef_getNullState (u->sref);
10692
10693 if (sRefSet_size (prefs) == 1)
10694 {
10695 res = sRefSet_choose (prefs);
10696 }
10697 else
10698 {
28bf4b0b 10699 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
616915dd 10700 res = sRefSet_mergeIntoOne (prefs);
10701 }
10702
10703 if (nstate_isKnown (n))
10704 {
10705 sRef_setNullState (res, n, g_currentloc);
10706 }
10707 }
10708 else
10709 {
10710 if (ctype_isFunction (u->utype))
10711 {
28bf4b0b 10712 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10713 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
616915dd 10714 }
10715 else
10716 {
10717 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10718 }
10719
10720 if (sRef_isRefCounted (res))
10721 {
10722 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10723 }
10724 }
10725
28bf4b0b 10726
616915dd 10727 if (sRef_getNullState (res) == NS_ABSNULL)
10728 {
10729 ctype ct = ctype_realType (u->utype);
10730
10731 if (ctype_isAbstract (ct))
10732 {
10733 sRef_setNotNull (res, g_currentloc);
10734 }
10735 else
10736 {
10737 if (ctype_isUser (ct))
10738 {
10739 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10740 }
10741 else
10742 {
10743 sRef_setNotNull (res, g_currentloc);
10744 }
10745 }
10746 }
10747
10748 if (sRef_isRefCounted (res))
10749 {
10750 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10751 }
10752 else if (sRef_isKillRef (res))
10753 {
10754 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10755 }
10756 else
10757 {
10758 ;
10759 }
10760
10761 ak = sRef_getAliasKind (res);
10762
10763 if (alkind_isImplicit (ak))
10764 {
10765 sRef_setAliasKind (res,
10766 alkind_fixImplicit (ak),
10767 g_currentloc);
10768 }
10769
10770 sRefSet_free (prefs);
10771
28bf4b0b 10772 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
616915dd 10773 return res;
10774 }
10775}
10776
10777static bool uentry_isRefCounted (uentry ue)
10778{
10779 ctype ct = uentry_getType (ue);
10780
10781 if (ctype_isFunction (ct))
10782 {
28bf4b0b 10783 return (ctype_isRefCounted (ctype_getReturnType (ct)));
616915dd 10784 }
10785 else
10786 {
10787 return (ctype_isRefCounted (ct));
10788 }
10789}
10790
10791/*
10792** old was declared yield in the specification.
10793** new is declared in the iter implementation.
10794*/
10795
10796void uentry_checkYieldParam (uentry old, uentry unew)
10797{
10798 cstring name;
10799
10800 llassert (uentry_isVariable (old));
10801 llassert (uentry_isVariable (unew));
10802
10803 unew->info->var->kind = VKYIELDPARAM;
10804 (void) checkTypeConformance (old, unew, TRUE);
10805 checkVarConformance (old, unew, TRUE, FALSE);
10806
10807 /* get rid of param marker */
10808
10809 name = uentry_getName (unew);
10810 cstring_free (unew->uname);
10811 unew->uname = name;
10812 unew->info->var->kind = VKREFYIELDPARAM;
10813
10814 uentry_setUsed (old, fileloc_undefined);
10815 uentry_setUsed (unew, fileloc_undefined);
10816}
10817
10818/*@observer@*/ cstring
10819uentry_ekindName (uentry ue)
10820{
10821 if (uentry_isValid (ue))
10822 {
10823 switch (ue->ukind)
10824 {
10825 case KINVALID:
10826 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10827 case KDATATYPE:
10828 return cstring_makeLiteralTemp ("Datatype");
10829 case KENUMCONST:
10830 return cstring_makeLiteralTemp ("Enum member");
10831 case KCONST:
10832 return cstring_makeLiteralTemp ("Constant");
10833 case KVAR:
10834 if (uentry_isParam (ue))
10835 {
10836 return cstring_makeLiteralTemp ("Parameter");
10837 }
10838 else if (uentry_isExpandedMacro (ue))
10839 {
10840 return cstring_makeLiteralTemp ("Expanded macro");
10841 }
10842 else
10843 {
10844 return cstring_makeLiteralTemp ("Variable");
10845 }
10846 case KFCN:
10847 return cstring_makeLiteralTemp ("Function");
10848 case KITER:
10849 return cstring_makeLiteralTemp ("Iterator");
10850 case KENDITER:
10851 return cstring_makeLiteralTemp ("Iterator finalizer");
10852 case KSTRUCTTAG:
10853 return cstring_makeLiteralTemp ("Struct tag");
10854 case KUNIONTAG:
10855 return cstring_makeLiteralTemp ("Union tag");
10856 case KENUMTAG:
10857 return cstring_makeLiteralTemp ("Enum tag");
10858 case KELIPSMARKER:
10859 return cstring_makeLiteralTemp ("Optional parameters");
10860 }
10861 }
10862 else
10863 {
10864 return cstring_makeLiteralTemp ("<Undefined>");
10865 }
10866
10867 BADEXIT;
10868}
10869
28bf4b0b 10870/*@observer@*/ cstring
10871uentry_ekindNameLC (uentry ue)
10872{
10873 if (uentry_isValid (ue))
10874 {
10875 switch (ue->ukind)
10876 {
10877 case KINVALID:
10878 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10879 case KDATATYPE:
10880 return cstring_makeLiteralTemp ("datatype");
10881 case KENUMCONST:
10882 return cstring_makeLiteralTemp ("enum member");
10883 case KCONST:
10884 return cstring_makeLiteralTemp ("constant");
10885 case KVAR:
10886 if (uentry_isParam (ue))
10887 {
10888 return cstring_makeLiteralTemp ("parameter");
10889 }
10890 else if (uentry_isExpandedMacro (ue))
10891 {
10892 return cstring_makeLiteralTemp ("expanded macro");
10893 }
10894 else
10895 {
10896 return cstring_makeLiteralTemp ("variable");
10897 }
10898 case KFCN:
10899 return cstring_makeLiteralTemp ("function");
10900 case KITER:
10901 return cstring_makeLiteralTemp ("iterator");
10902 case KENDITER:
10903 return cstring_makeLiteralTemp ("iterator finalizer");
10904 case KSTRUCTTAG:
10905 return cstring_makeLiteralTemp ("struct tag");
10906 case KUNIONTAG:
10907 return cstring_makeLiteralTemp ("union tag");
10908 case KENUMTAG:
10909 return cstring_makeLiteralTemp ("enum tag");
10910 case KELIPSMARKER:
10911 return cstring_makeLiteralTemp ("optional parameters");
10912 }
10913 }
10914 else
10915 {
10916 return cstring_makeLiteralTemp ("<Undefined>");
10917 }
10918
10919 BADEXIT;
10920}
10921
616915dd 10922void uentry_setHasNameError (uentry ue)
10923{
10924 llassert (uentry_isValid (ue));
10925
10926 ue->hasNameError = TRUE;
10927}
10928
10929void uentry_checkName (uentry ue)
10930{
28bf4b0b 10931 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10932 uentry_observeRealName (ue),
10933 bool_unparse (uentry_isVisibleExternally (ue))));
10934
616915dd 10935 if (uentry_isValid (ue)
28bf4b0b 10936 && !context_inXHFile ()
10937 && uentry_hasName (ue)
616915dd 10938 && !uentry_isElipsisMarker (ue)
10939 && context_getFlag (FLG_NAMECHECKS)
10940 && !ue->hasNameError
10941 && !uentry_isEndIter (ue)
10942 && !fileloc_isBuiltin (uentry_whereLast (ue))
10943 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
28bf4b0b 10944 {
10945 DPRINTF (("Here..."));
10946
616915dd 10947 if (uentry_isPriv (ue))
10948 {
10949 ; /* any checks here? */
10950 }
10951 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10952 {
10953 ; /* no errors for externals */
10954 }
10955 else
10956 {
10957 int scope;
10958
10959 if (uentry_isExpandedMacro (ue))
10960 {
10961 scope = globScope;
10962 }
10963 else
10964 {
10965 if (uentry_isExpandedMacro (ue))
10966 {
10967 scope = fileScope;
10968 }
10969 else if (uentry_isVariable (ue))
10970 {
10971 sRef sr = uentry_getSref (ue);
10972
10973 if (sRef_isValid (sr))
10974 {
10975 scope = sRef_getScope (sr);
10976 }
10977 else
10978 {
10979 scope = fileScope;
10980 }
10981 }
10982 else if (uentry_isFunction (ue)
10983 || uentry_isIter (ue)
10984 || uentry_isEndIter (ue)
10985 || uentry_isConstant (ue))
10986 {
10987 scope = uentry_isStatic (ue) ? fileScope : globScope;
10988 }
10989 else /* datatypes, etc. must be global */
10990 {
10991 scope = globScope;
10992 }
10993
10994 usymtab_checkDistinctName (ue, scope);
10995 }
28bf4b0b 10996
616915dd 10997 if (context_getFlag (FLG_CPPNAMES))
10998 {
28bf4b0b 10999 checkCppName (ue);
616915dd 11000 }
11001
11002 if (scope == globScope)
11003 {
28bf4b0b 11004 checkExternalName (ue);
616915dd 11005 }
28bf4b0b 11006 else if (scope == fileScope)
11007 {
11008 checkFileScopeName (ue);
11009 }
11010 else
616915dd 11011 {
11012 checkLocalName (ue);
616915dd 11013 }
11014
616915dd 11015 checkPrefix (ue);
28bf4b0b 11016 checkAnsiName (ue);
616915dd 11017 }
11018 }
11019}
11020
7ebcc5bb 11021/*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
616915dd 11022{
11023 uentry ue;
11024 fileloc tloc;
11025
11026 /*
7ebcc5bb 11027 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11028 */
11029
616915dd 11030 if (!context_inMacro ())
11031 {
11032 sRef_setGlobalScopeSafe ();
11033 }
11034
11035 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11036 uentry_setUsed (ue, loc);
11037
11038 tloc = fileloc_createExternal ();
11039 uentry_setDefined (ue, tloc);
11040 fileloc_free (tloc);
11041 uentry_setHasNameError (ue);
11042
11043 if (context_getFlag (FLG_REPEATUNRECOG))
11044 {
11045 uentry_markOwned (ue);
11046 }
11047 else
11048 {
11049 ue = usymtab_supReturnFileEntry (ue);
11050 }
11051
11052 if (!context_inMacro ())
11053 {
11054 sRef_clearGlobalScopeSafe ();
11055 }
11056
11057 return ue;
11058}
11059
28bf4b0b 11060uentry uentry_makeGlobalMarker ()
11061{
11062 uentry ue;
11063 fileloc tloc;
11064
11065 llassert (sRef_inGlobalScope ());
11066
11067 ue = uentry_makeVariableAux
11068 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11069 sRef_makeGlobalMarker (),
11070 FALSE, VKNORMAL);
11071
11072 tloc = fileloc_createExternal ();
11073 uentry_setUsed (ue, tloc);
11074 uentry_setDefined (ue, tloc);
11075 fileloc_free (tloc);
11076 uentry_setHasNameError (ue);
11077
11078 return ue;
11079}
11080
11081
11082bool uentry_isGlobalMarker (uentry ue)
11083{
11084 return (uentry_isValid (ue)
11085 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11086}
11087
616915dd 11088/* new start modifications */
28bf4b0b 11089
616915dd 11090/* start modifications */
11091/*
11092requires: p_e is defined, is a ptr/array variable
11093modifies: p_e
11094effects: sets the state of the variable
11095*/
11096
28bf4b0b 11097
616915dd 11098void uentry_setPossiblyNullTerminatedState (uentry p_e) {
b7b694d6 11099 /*@access sRef@*/ /*i523 shouldn't do this! */
616915dd 11100 if( uentry_isValid(p_e) ) {
11101 if( p_e->info != NULL) {
11102 if( p_e->info->var != NULL) {
11103 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11104 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11105 return;
b7b694d6 11106 }
11107 }
11108 }
11109 /*@noaccess sRef@*/
616915dd 11110
11111 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11112}
11113
11114/*
11115requires: p_e is defined, is a ptr/array variable
11116modifies: p_e
11117effects: sets the size of the buffer
11118*/
11119
11120void uentry_setNullTerminatedState (uentry p_e) {
11121 if( uentry_isValid(p_e) ) {
11122 if( p_e->info != NULL) {
11123 if( p_e->info->var != NULL) {
11124 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
b7b694d6 11125 /*@access sRef@*/ /*@i523 bad!*/
616915dd 11126 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
b7b694d6 11127 /*@noaccess sRef@*/
616915dd 11128 return;
b7b694d6 11129 }
11130 }
11131 }
616915dd 11132
11133 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11134}
11135
616915dd 11136/*
11137requires: p_e is defined, is a ptr/array variable
11138modifies: p_e
11139effects: sets the size of the buffer
11140*/
11141
11142void uentry_setSize (uentry p_e, int size) {
11143 if( uentry_isValid(p_e) ) {
11144 if( p_e->info != NULL) {
11145 if( p_e->info->var != NULL) {
11146 p_e->info->var->bufinfo->size = size;
b7b694d6 11147 /*@access sRef@*/ /*@i523 bad!*/
616915dd 11148 p_e->sref->bufinfo.size = size;
b7b694d6 11149 /*@noaccess sRef@*/
616915dd 11150 return;
b7b694d6 11151 }
11152 }
11153 }
616915dd 11154
11155 fprintf(stderr, "uentry:Error in setSize\n");
11156}
11157
11158
11159/*
11160requires: p_e is defined, is a ptr/array variable
11161modifies: p_e
11162effects: sets the length of the buffer
11163*/
11164
b7b694d6 11165void uentry_setLen (uentry p_e, int len) {
616915dd 11166 if( uentry_isValid(p_e) ) {
11167 if( p_e->info != NULL) {
11168 if( p_e->info->var != NULL) {
11169 p_e->info->var->bufinfo->len = len;
b7b694d6 11170 /*@access sRef@*/ /*@i523 bad!*/
616915dd 11171 p_e->sref->bufinfo.len = len;
b7b694d6 11172 /*@noaccess sRef@*/
616915dd 11173 return;
b7b694d6 11174 }
11175 }
11176 }
11177
616915dd 11178 fprintf(stderr, "uentry:Error in setLen\n");
11179}
b7b694d6 11180
616915dd 11181/*@=type*/
ba45e1e4 11182
11183bool uentry_hasMetaStateEnsures (uentry e)
11184{
11185 if (uentry_isValid (e) && uentry_isFunction (e))
11186 {
11187 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11188 }
11189 else
11190 {
11191 return FALSE;
11192 }
11193}
11194
ccf0a4a8 11195metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
ba45e1e4 11196{
ccf0a4a8 11197 llassert (uentry_isValid (e) && uentry_isFunction (e));
11198 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
ba45e1e4 11199}
This page took 7.058684 seconds and 5 git commands to generate.