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