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