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