2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://www.splint.org
28 # include "lclintMacros.nf"
30 # include "structNames.h"
31 # include "nameChecks.h"
33 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34 static /*@only@*/ fileloc posLoc = fileloc_undefined;
35 static int nuentries = 0;
36 static int totuentries = 0;
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);
46 static void uentry_showWhereLastKind (uentry p_spec) /*@*/ ;
48 static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
51 static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
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@*/ ;
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@*/;
70 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
71 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
74 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
76 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
77 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
80 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
81 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
82 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
83 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
84 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
86 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
87 ctype p_oldType, /*@notnull@*/ uentry p_unew,
88 /*@notnull@*/ uentry p_newCurrent,
89 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
91 static /*@only@*/ /*@notnull@*/ uentry
92 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
93 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
95 static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
97 if (uentry_isVariable (ue)
98 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
99 || ctype_isUnknown (uentry_getType (ue))))
101 uentry_makeVarFunction (ue);
105 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
107 uentry ue = (uentry) dmalloc (sizeof (*ue));
108 ue->warn = warnClause_undefined; /*@i32@*/
115 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
116 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
118 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
119 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
120 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
121 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
122 static void ucinfo_free (/*@only@*/ ucinfo p_u);
123 static void uvinfo_free (/*@only@*/ uvinfo p_u);
127 static /*@only@*/ cstring ancontext_unparse (ancontext an)
131 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
132 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
133 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
134 case AN_SUFIELD: return cstring_makeLiteral ("su field");
135 case AN_TDEFN: return cstring_makeLiteral ("type definition");
136 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
137 case AN_CONST: return cstring_makeLiteral ("constant");
143 static int annots[AN_LAST][QU_LAST];
144 static int decls[AN_LAST];
145 static int shdecls[AN_LAST];
146 static int idecls[AN_LAST];
152 for (i = AN_UNKNOWN; i < AN_LAST; i++)
158 for (j = QU_UNKNOWN; j < QU_LAST; j++)
165 static void tallyAnnot (ancontext ac, qual q)
179 for (j = QU_UNKNOWN; j < QU_LAST; j++)
184 for (i = AN_UNKNOWN; i < AN_LAST; i++)
190 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
191 ancontext_unparse (i),
192 decls[i], shdecls[i], idecls[i]);
194 totdecls += decls[i];
195 totshdecls += shdecls[i];
196 totidecls += idecls[i];
198 for (j = QU_UNKNOWN; j < QU_LAST; j++)
200 total[j] += annots[i][j];
201 alltotals += annots[i][j];
204 printf (" Allocation:\n");
208 for (j = QU_UNKNOWN; j < QU_LAST; j++)
210 if (qual_isAliasQual (j) && !qual_isUnique (j))
212 if (annots[i][j] > 0)
214 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
215 100.0 * (double)annots[i][j] / (double)decls[i]);
216 tmptot += annots[i][j];
221 printf (" Exposure:\n");
225 for (j = QU_UNKNOWN; j < QU_LAST; j++)
227 if (qual_isExQual (j))
229 if (annots[i][j] > 0)
231 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
232 100.0 * (double)annots[i][j] / (double)decls[i]);
233 tmptot += annots[i][j];
238 printf (" Definition:\n");
240 for (j = QU_UNKNOWN; j < QU_LAST; j++)
242 if (qual_isAllocQual (j))
244 if (annots[i][j] > 0)
246 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
247 100.0 * (double)annots[i][j] / (double)decls[i]);
254 for (j = QU_UNKNOWN; j < QU_LAST; j++)
256 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
258 if (annots[i][j] > 0)
260 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
261 100.0 * (double)annots[i][j] / (double)decls[i]);
270 for (j = QU_UNKNOWN; j < QU_LAST; j++)
274 for (i = AN_UNKNOWN; i < AN_LAST; i++)
276 if (annots[i][j] > 0)
285 printf ("Annotation: %s\n", qual_unparse (j));
287 for (i = AN_UNKNOWN; i < AN_LAST; i++)
289 if (annots[i][j] > 0)
291 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
298 printf ("All Contexts\n");
300 for (j = QU_UNKNOWN; j < QU_LAST; j++)
304 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
305 100.0 * (double)total[j] / (double)(totdecls));
310 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
312 extern void uentry_tallyAnnots (uentry u, ancontext kind)
314 alkind ak = sRef_getAliasKind (u->sref);
315 exkind ek = sRef_getExKind (u->sref);
316 nstate ns = sRef_getNullState (u->sref);
317 sstate ss = sRef_getDefState (u->sref);
318 bool recordUnknown = FALSE;
320 if (kind == AN_UNKNOWN)
328 else if (e == KCONST || e == KENUMCONST)
332 else if (e == KFCN || e == KITER)
334 uentryList params = uentry_getParams (u);
337 uentryList_elements (params, current)
339 if (uentry_isReturned (current))
343 if (!uentry_isElipsisMarker (current))
345 uentry_tallyAnnots (current, AN_FCNPARAM);
347 } end_uentryList_elements;
351 if (ctype_isFunction (u->utype)
353 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
355 recordUnknown = TRUE;
358 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
360 ctype t = ctype_realType (u->utype);
364 uentryList fields = ctype_getFields (t);
366 uentryList_elements (fields, current)
368 uentry_tallyAnnots (current, AN_SUFIELD);
370 } end_uentryList_elements;
374 if (ctype_isVisiblySharable (u->utype))
376 recordUnknown = TRUE;
384 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
386 recordUnknown = TRUE;
393 if (kind == AN_FCNRETURN)
407 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
412 if (ctype_isRealPointer (ctype_realType (u->utype)))
420 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
421 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
422 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
423 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
427 if (uentry_isReturned (u))
429 tallyAnnot (kind, QU_RETURNED);
435 if (ctype_isRefCounted (ctype_realType (u->utype))
436 || (ctype_isFunction (u->utype) &&
437 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
443 if (kind == AN_FCNPARAM)
445 tallyAnnot (kind, QU_TEMP);
447 else if (recordUnknown)
449 if (kind == AN_FCNRETURN)
452 tallyAnnot (kind, QU_UNKNOWN);
456 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
457 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
458 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
459 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
461 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
462 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
463 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
464 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
465 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
466 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
467 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
468 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
469 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
470 case AK_IMPDEPENDENT:
471 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
481 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
482 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
488 case NS_ERROR: break;
489 case NS_UNKNOWN: break;
490 case NS_NOTNULL: break;
491 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
492 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
493 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
494 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
496 case NS_ABSNULL: break;
502 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
506 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
507 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
508 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
509 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
510 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
516 static specCode specCode_fromInt (int i)
519 llassert (i >= SPC_NONE && i < SPC_LAST);
521 return ((specCode) i);
525 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
527 if (uentry_isDeclared (u))
529 return cstring_makeLiteralTemp ("previously declared");
533 return cstring_makeLiteralTemp ("specified");
537 /*@observer@*/ cstring uentry_specDeclName (uentry u)
539 if (uentry_isDeclared (u))
541 return cstring_makeLiteralTemp ("previous declaration");
545 return cstring_makeLiteralTemp ("specification");
549 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
551 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
553 return cstring_makeLiteralTemp ("redefined");
555 else if (uentry_isCodeDefined (unew))
557 return cstring_makeLiteralTemp ("defined");
559 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
561 return cstring_makeLiteralTemp ("redeclared");
565 return cstring_makeLiteralTemp ("declared");
569 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
571 if (uentry_isValid (ue))
573 functionConstraint constraint;
575 DPRINTF( (message ("called uentry_getFcnPostconditions on %s",
576 uentry_unparse (ue) ) ) );
578 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
580 DPRINTF( (message ("called uentry_getFunctionConditions on nonfunction %s",
581 uentry_unparse (ue) ) ) );
582 if (!uentry_isFunction (ue) )
584 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
585 uentry_unparse (ue) ) ));
586 return constraintList_undefined;
590 return constraintList_undefined;
593 if (!uentry_isFunction(ue))
596 DPRINTF( (message ("called uentry_getFunctionConditions on non function %s",
597 uentry_unparse (ue) ) ) );
598 return constraintList_undefined;
602 llassert (uentry_isFunction (ue));
606 constraint = ue->info->fcn->postconditions;
610 constraint = ue->info->fcn->preconditions;
613 return functionConstraint_getBufferConstraints (constraint);
616 return constraintList_undefined;
621 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
623 return uentry_getFunctionConditions (ue, FALSE);
630 constraintList uentry_getFcnPostconditions (uentry ue)
632 return uentry_getFunctionConditions (ue, TRUE);
635 static /*@only@*/ fileloc setLocation (void)
637 fileloc fl = context_getSaveLocation ();
639 if (fileloc_isDefined (fl))
645 return fileloc_copy (g_currentloc);
649 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
651 llassert (uentry_isEitherConstant (ue));
652 sRef_setValue (ue->sref, val);
655 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
657 fileloc loc = setLocation ();
658 uentry ue = uentry_makeConstant (n, t, loc);
660 ue->ukind = KENUMCONST;
661 uentry_setDefined (ue, loc);
665 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
667 fileloc loc = setLocation ();
668 uentry ue = uentry_makeConstant (n, t, loc);
669 ctype etype = exprNode_getType (expr);
671 if (!ctype_isRealInt (etype)) {
675 ("Value of enum member is not an integeral type (type %s): %s",
676 ctype_unparse (etype), exprNode_unparse (expr)),
677 exprNode_loc (expr));
680 ue->ukind = KENUMCONST;
681 uentry_setDefined (ue, loc);
686 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
688 uentry ue = uentry_makeConstant (n, t, loc);
690 ue->ukind = KENUMCONST;
695 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
697 return uentry_makeVariable (n, t, setLocation (), FALSE);
701 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
703 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
707 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
709 ctype ct = idDecl_getCtype (id);
710 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
711 MAYBE, MAYBE, setLocation ());
713 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
715 if (!ynm_isOn (ue->info->datatype->abs))
717 if (ctype_isUnknown (ct))
719 ue->info->datatype->mut = MAYBE;
723 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
730 void uentry_checkParams (uentry ue)
732 if (uentry_isValid (ue))
734 bool isExt = uentry_isExtern (ue);
736 if (uentry_isRealFunction (ue))
738 uentryList params = uentry_getParams (ue);
740 uentryList_elements (params, current)
742 if (uentry_isValid (current))
744 ctype ct = current->utype;
746 if (ctype_isFixedArray (ct))
748 if (ctype_isArray (ctype_baseArrayPtr (ct))
749 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
756 (FLG_FIXEDFORMALARRAY,
757 message ("Function parameter %q declared as "
758 "manifest array (size constant is meaningless)",
759 uentry_getName (current)),
760 uentry_whereDeclared (current));
765 if (ctype_isArray (ct))
769 message ("Function parameter %q declared as "
770 "array (treated as pointer)",
771 uentry_getName (current)),
772 uentry_whereDeclared (current));
776 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
778 if (ctype_isAbstract (ct) &&
779 (isExt || (ctype_isAbstract (ctype_realType (ct))
780 && !context_hasFileAccess (ctype_typeId (ct)))))
785 ("Function %q declared with notnull parameter %q of abstract "
788 uentry_getName (current),
791 ("Since %s is an abstract type, notnull can only be "
792 "used for parameters if the function is static to a "
793 "module where %s is accessible.",
796 uentry_whereDeclared (current));
800 } end_uentryList_elements;
802 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
804 ctype ct = ue->utype;
806 if (ctype_isAbstract (ct)
807 && (isExt || (ctype_isAbstract (ctype_realType (ct))
808 && !context_hasFileAccess (ctype_typeId (ct)))))
813 ("%s %q declared %s notnull storage of abstract type %s",
814 ekind_capName (uentry_getKind (ue)),
819 ("Since %s is an abstract type, notnull can only be used "
820 "if it is static to a module where %s is accessible.",
823 uentry_whereDeclared (ue));
830 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
832 alkind ak = sRef_getAliasKind (ue->sref);
834 if (alkind_isRefCounted (ak))
836 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
840 if (alkind_isUnknown (ak))
842 exkind ek = sRef_getExKind (ue->sref);
844 if (exkind_isKnown (ek))
846 DPRINTF (("Setting imp dependent: %s",
847 uentry_unparseFull (ue)));
848 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
852 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
854 /* evans 2000-12-22 removed ctype_realType so it will
855 not apply to immutable abstract types. */
857 if (ctype_isVisiblySharable
858 (ctype_realType (ctype_getReturnType (ue->utype))))
860 if (uentryList_hasReturned (uentry_getParams (ue)))
866 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
868 ; /* Immutable objects are not shared. */
872 sRef_setAliasKind (ue->sref, AK_IMPONLY,
874 DPRINTF (("Ret imp only: %s",
875 ctype_unparse (ctype_getReturnType (ue->utype))));
885 static /*@notnull@*/ uentry
886 uentry_makeFunctionAux (cstring n, ctype t,
888 /*@only@*/ globSet globs,
889 /*@only@*/ sRefSet mods,
890 /*@only@*/ warnClause warn,
891 /*@keep@*/ fileloc f, bool priv,
892 /*@unused@*/ bool isForward)
894 uentry e = uentry_alloc ();
897 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
899 DPRINTF (("Make function: %s", n));
901 if (ctype_isFunction (t))
903 ret = ctype_getReturnType (t);
907 if (ctype_isKnown (t))
909 llbug (message ("not function: %s", ctype_unparse (t)));
916 if (fileloc_isSpec (f) || fileloc_isImport (f))
918 e->whereSpecified = f;
919 e->whereDeclared = fileloc_undefined;
923 e->whereSpecified = fileloc_undefined;
924 e->whereDeclared = f;
927 /* e->shallowCopy = FALSE; */
928 e->uname = cstring_copy (n);
930 e->storageclass = SCNONE;
932 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
934 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
936 if (ctype_isUA (ret))
938 sRef_setStateFromType (e->sref, ret);
943 e->uses = filelocList_new ();
945 e->hasNameError = FALSE;
949 e->info = (uinfo) dmalloc (sizeof (*e->info));
950 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
952 e->info->fcn->hasMods = sRefSet_isDefined (mods);
953 e->info->fcn->hasGlobs = globSet_isDefined (globs);
955 e->info->fcn->exitCode = XK_UNKNOWN;
956 e->info->fcn->nullPred = qual_createUnknown ();
957 e->info->fcn->specialCode = SPC_NONE;
959 e->info->fcn->access = access;
960 e->info->fcn->globs = globs;
961 e->info->fcn->defparams = uentryList_undefined;
963 sRef_setDefined (e->sref, f);
964 e->whereDefined = fileloc_undefined;
966 e->info->fcn->mods = sRefSet_undefined;
967 e->info->fcn->specclauses = NULL;
970 e->info->fcn->preconditions = NULL;
974 e->info->fcn->postconditions = NULL;
977 checkGlobalsModifies (e, mods);
978 e->info->fcn->mods = mods;
983 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
985 functionClauseList_elements (clauses, el)
987 DPRINTF (("Reflect clause: %s on %s",
988 functionClause_unparse (el), uentry_getName (ue)));
990 if (functionClause_isNoMods (el))
992 modifiesClause mel = functionClause_getModifies (el);
994 if (uentry_hasGlobs (ue))
999 ("No globals and modifies inconsistent to globals clause for %q: %q",
1000 uentry_getName (ue),
1001 globSet_unparse (uentry_getGlobs (ue))),
1002 modifiesClause_getLoc (mel));
1006 if (uentry_hasMods (ue))
1011 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1012 uentry_getName (ue),
1013 sRefSet_unparse (uentry_getMods (ue))),
1014 modifiesClause_getLoc (mel));
1017 uentry_setGlobals (ue, globSet_undefined);
1018 uentry_setModifies (ue, sRefSet_undefined);
1020 else if (functionClause_isGlobals (el))
1022 globalsClause glc = functionClause_getGlobals (el);
1024 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1025 globalsClause_unparse (glc)));
1027 if (uentry_hasGlobs (ue))
1032 ("Multiple globals clauses for %q: %q",
1033 uentry_getName (ue),
1034 globalsClause_unparse (glc)),
1035 globalsClause_getLoc (glc));
1036 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1040 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1043 else if (functionClause_isModifies (el))
1045 modifiesClause mlc = functionClause_getModifies (el);
1047 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1049 if (uentry_hasMods (ue))
1057 ("Multiple modifies clauses for %s: %s",
1058 uentry_getName (ue),
1059 modifiesClause_unparse (mlc)),
1060 modifiesClause_getLoc (mlc)))
1062 llhint (message ("Previous modifies clause: ",
1063 sRefSet_unparse (uentry_getMods (ue))));
1069 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1073 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1076 else if (functionClause_isEnsures (el))
1078 functionConstraint cl = functionClause_takeEnsures (el);
1079 DPRINTF (("Setting post: %s / %s",
1080 uentry_unparse (ue), functionConstraint_unparse (cl)));
1081 uentry_setPostconditions (ue, cl);
1083 else if (functionClause_isRequires (el))
1085 functionConstraint cl = functionClause_takeRequires (el);
1086 uentry_setPreconditions (ue, cl);
1088 else if (functionClause_isState (el))
1090 stateClause sc = functionClause_takeState (el);
1092 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1094 sRefSet rfs = stateClause_getRefs (sc);
1096 sRefSet_elements (rfs, s)
1098 if (sRef_isParam (s))
1101 ** Can't use requires on parameters
1105 (FLG_ANNOTATIONERROR,
1106 message ("Requires clauses for %q concerns parameters %q should be "
1107 "a parameter annotation instead: %q",
1108 uentry_unparse (ue),
1110 stateClause_unparse (sc)),
1111 stateClause_loc (sc));
1113 } end_sRefSet_elements ;
1116 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1117 uentry_addStateClause (ue, sc);
1119 else if (functionClause_isWarn (el))
1121 warnClause wc = functionClause_takeWarn (el);
1122 uentry_addWarning (ue, wc);
1126 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1128 } end_functionClauseList_elements ;
1130 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1131 stateClauseList_checkAll (ue);
1134 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1136 bool leaveFunc = FALSE;
1138 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1139 typeId_invalid, globSet_undefined,
1140 sRefSet_undefined, warnClause_undefined,
1143 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1146 ** This makes parameters names print out correctly.
1147 ** (But we might be a local variable declaration for a function type...)
1150 if (context_inFunctionLike ())
1152 DPRINTF (("Header: %s / %s",
1153 uentry_unparse (context_getHeader ()),
1154 idDecl_unparse (id)));
1158 context_enterFunctionDeclaration (ue);
1162 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1163 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1164 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1165 reflectImplicitFunctionQualifiers (ue, FALSE);
1166 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1167 uentry_reflectClauses (ue, idDecl_getClauses (id));
1168 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1170 if (!uentry_isStatic (ue)
1171 && cstring_equalLit (ue->uname, "main"))
1173 ctype typ = ue->utype;
1177 llassert (ctype_isFunction (typ));
1179 retval = ctype_getReturnType (typ);
1181 if (!ctype_isInt (retval))
1185 message ("Function main declared to return %s, should return int",
1186 ctype_unparse (retval)),
1187 uentry_whereDeclared (ue));
1190 args = ctype_argsFunction (typ);
1192 if (uentryList_isMissingParams (args)
1193 || uentryList_size (args) == 0)
1199 if (uentryList_size (args) != 2)
1203 message ("Function main declared with %d arg%&, "
1204 "should have 2 (int argc, char *argv[])",
1205 uentryList_size (args)),
1206 uentry_whereLast (ue));
1210 uentry arg = uentryList_getN (args, 0);
1211 ctype ct = uentry_getType (arg);
1213 if (!ctype_isInt (ct))
1217 message ("Parameter 1, %q, of function main declared "
1218 "with type %t, should have type int",
1219 uentry_getName (arg), ct),
1220 uentry_whereDeclared (arg));
1223 arg = uentryList_getN (args, 1);
1224 ct = uentry_getType (arg);
1226 if (ctype_isArrayPtr (ct)
1227 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1228 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1236 message ("Parameter 2, %q, of function main declared "
1237 "with type %t, should have type char **",
1238 uentry_getName (arg), ct),
1239 uentry_whereDeclared (arg));
1247 context_exitFunctionDeclaration ();
1253 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1255 alkind ak = sRef_getAliasKind (e->sref);
1257 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1258 && context_getFlag (FLG_PARAMIMPTEMP))
1260 exkind ek = sRef_getExKind (e->sref);
1262 if (exkind_isKnown (ek))
1264 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1265 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1266 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1270 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1271 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1276 static /*@only@*/ /*@notnull@*/ uentry
1277 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1278 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1280 cstring pname = makeParam (n);
1283 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1284 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1286 cstring_free (pname);
1287 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1288 uentry_implicitParamAnnots (e);
1289 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1291 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1293 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1294 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1295 e->info->var->defstate = defstate;
1298 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1304 uentry_setRefCounted (uentry e)
1306 if (uentry_isValid (e))
1308 uentry_setAliasKind (e, AK_REFCOUNTED);
1309 sRef_storeState (e->sref);
1315 uentry_setStatic (uentry c)
1317 if (uentry_isValid (c))
1319 alkind ak = sRef_getAliasKind (c->sref);
1320 c->storageclass = SCSTATIC;
1322 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1324 if (!alkind_isUnknown (ak)
1325 && !alkind_isStatic (ak))
1327 if (!(ctype_isRealPointer (uentry_getType (c)))
1328 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1329 && !alkind_isRefCounted (ak))
1331 if (alkind_isImplicit (ak)
1332 && alkind_isDependent (ak)
1333 && ctype_isArray (uentry_getType (c)))
1335 ; /* no error for observer arrays */
1341 message ("Static storage %q declared as %s",
1343 alkind_unparse (ak)),
1344 uentry_whereDeclared (c));
1350 if (alkind_isUnknown (ak)
1351 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1352 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1354 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1355 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1363 uentry_setExtern (uentry c)
1365 if (uentry_isValid (c))
1366 c->storageclass = SCEXTERN;
1370 uentry_setParamNo (uentry ue, int pno)
1372 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1373 sRef_setParamNo (ue->sref, pno);
1377 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1379 sRefSet_allElements (sr, el)
1381 sRef base = sRef_getRootBase (el);
1383 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1384 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1386 if (!globSet_member (ue->info->fcn->globs, base))
1388 if (uentry_hasGlobs (ue)
1389 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1392 (FLG_WARNMISSINGGLOBALS,
1394 ("Modifies list for %q uses global %q, "
1395 "not included in globals list.",
1396 uentry_getName (ue),
1397 sRef_unparse (base)),
1398 uentry_whereLast (ue)))
1400 uentry_showWhereSpecified (ue);
1404 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1406 if (sRef_isFileStatic (base))
1408 context_recordFileGlobals (ue->info->fcn->globs);
1412 } end_sRefSet_allElements;
1416 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1418 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1422 uentry_fixupSref (uentry ue)
1426 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1431 sr = uentry_getSref (ue);
1433 sRef_resetState (sr);
1434 sRef_clearDerived (sr);
1436 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1437 llassert (sRef_isValid (sr));
1439 if (uentry_isVariable (ue))
1441 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1442 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1443 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1447 static void uentry_addStateClause (uentry ue, stateClause sc)
1450 ** Okay to allow multiple clauses of the same kind.
1451 */ /*@i834 is this true?@*/
1453 ue->info->fcn->specclauses =
1454 stateClauseList_add (ue->info->fcn->specclauses, sc);
1456 /* Will call checkAll to check later... */
1459 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1461 llassert (uentry_isFunction (ue));
1462 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1464 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1465 ue->info->fcn->specclauses = clauses;
1466 stateClauseList_checkAll (ue);
1467 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1471 ** Used for @modifies@ @endmodifies@ syntax.
1473 ** If ue is specified, sr must contain *only*:
1475 ** o file static globals
1476 ** o sRef's derived from modifies spec (i.e., more specific than
1477 ** what was specified)
1479 ** Otherwise, if sr has modifies it must match sr.
1481 ** If it doesn't have modifies, set them to sr.
1485 uentry_checkModifiesContext (void)
1487 if (sRef_modInFunction ())
1491 ("Modifies list not in function context. "
1492 "A modifies list can only appear following the parameter list "
1493 "in a function declaration or header."));
1502 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1504 if (!uentry_checkModifiesContext ())
1510 if (uentry_isValid (ue))
1512 if (uentry_isIter (ue))
1514 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1515 ue->info->iter->mods = sr;
1519 uentry_convertVarFunction (ue);
1520 llassertfatal (uentry_isFunction (ue));
1521 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1523 ue->info->fcn->mods = sr;
1524 ue->info->fcn->hasMods = TRUE;
1526 checkGlobalsModifies (ue, sr);
1529 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1531 ue->info->fcn->hasGlobs = TRUE;
1534 if (sRefSet_hasStatic (ue->info->fcn->mods))
1536 context_recordFileModifies (ue->info->fcn->mods);
1546 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1549 ** Function already has one modifies clause (possibly from
1550 ** a specification).
1553 if (!uentry_checkModifiesContext ())
1558 llassert (uentry_isValid (ue));
1560 if (uentry_isIter (ue))
1562 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1566 llassertfatal (uentry_isFunction (ue));
1567 llassert (ue->info->fcn->hasMods);
1569 checkGlobalsModifies (ue, sr);
1570 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1572 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1574 ue->info->fcn->hasGlobs = TRUE;
1578 if (sRefSet_hasStatic (ue->info->fcn->mods))
1580 context_recordFileModifies (ue->info->fcn->mods);
1584 bool uentry_hasWarning (uentry ue)
1586 return (uentry_isValid (ue)
1587 && warnClause_isDefined (ue->warn));
1590 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1592 llassert (warnClause_isUndefined (ue->warn));
1597 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1599 if (sRef_modInFunction ())
1602 (message ("Precondition list not in function context. "
1603 "A precondition list can only appear following the parameter list "
1604 "in a function declaration or header."));
1606 /*@-mustfree@*/ return; /*@=mustfree@*/
1609 if (uentry_isValid (ue))
1611 uentry_convertVarFunction (ue);
1612 llassertfatal (uentry_isFunction (ue));
1614 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1617 I changed this so it didn't appear as a Splint bug
1618 among other things this gets triggered when there is
1619 a function with two requires clauses. Now Splint
1620 prints an error and tries to conjoin the lists.
1623 (message ("Duplicate precondition list"
1624 "Attemping the conjoin the requires clauses"
1628 /* should conjoin constraints? */
1630 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1634 ue->info->fcn->preconditions = preconditions;
1639 llfatalbug ( (message("uentry_setPreconditions called with invalid uentry") ));
1648 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1650 if (sRef_modInFunction ())
1653 (message ("Postcondition list not in function context. "
1654 "A postcondition list can only appear following the parameter list "
1655 "in a function declaration or header."));
1657 /*@-mustfree@*/ return; /*@=mustfree@*/
1660 if (uentry_isValid (ue))
1662 uentry_convertVarFunction (ue);
1663 llassertfatal (uentry_isFunction (ue));
1665 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1667 ue->info->fcn->postconditions = postconditions;
1671 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1676 llfatalbug ( (message("uentry_setPostconditions called with invalid uentry") ));
1681 ** requires: new and old are functions
1685 checkGlobalsConformance (/*@notnull@*/ uentry old,
1686 /*@notnull@*/ uentry unew,
1687 bool mustConform, bool completeConform)
1689 bool hasInternalState = FALSE;
1691 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1693 if (globSet_isDefined (unew->info->fcn->globs))
1695 globSet_allElements (unew->info->fcn->globs, el)
1697 if (sRef_isFileStatic (el))
1699 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1701 if (sRef_isInvalid (sr))
1703 bool hasError = FALSE;
1705 if (!hasInternalState
1706 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1707 sRef_makeInternalState ()))
1708 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1709 sRef_makeSpecState ())))
1712 && !uentry_isStatic (old)
1715 message ("Globals list for %q includes internal state, %q, "
1716 "but %s without globals internalState.",
1717 uentry_getName (old),
1719 uentry_specOrDefName (old)),
1720 uentry_whereLast (unew)))
1722 uentry_showWhereSpecified (old);
1726 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1727 sRef_makeInternalState ());
1728 hasInternalState = TRUE;
1732 && fileloc_sameFile (uentry_whereDeclared (unew),
1733 uentry_whereDeclared (old)))
1738 message ("Function %q inconsistently %rdeclared (in "
1739 "same file) with file static global %q in "
1741 uentry_getName (unew),
1742 uentry_isDeclared (old),
1744 uentry_whereDeclared (unew)))
1746 uentry_showWhereSpecified (old);
1751 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1752 context_recordFileGlobals (old->info->fcn->globs);
1756 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1758 if (sRef_isInvalid (sr))
1763 message ("Function %q inconsistently %rdeclared with "
1764 "%q in globals list",
1765 uentry_getName (unew),
1766 uentry_isDeclared (old),
1768 uentry_whereDeclared (unew)))
1770 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1771 uentry_showWhereSpecified (old);
1776 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1782 ("Function %q global %q inconsistently "
1783 "%rdeclared as %qout global",
1784 uentry_getName (unew),
1786 uentry_isDeclared (old),
1787 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1788 uentry_whereDeclared (unew)))
1790 uentry_showWhereSpecified (old);
1795 } end_globSet_allElements ;
1797 if (completeConform)
1799 globSet_allElements (old->info->fcn->globs, el)
1801 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1803 if (sRef_isInvalid (sr))
1806 && uentry_isReallySpecified (old)
1809 message ("Function %q specified with %q in globals list, "
1810 "but declared without %q",
1811 uentry_getName (unew),
1814 uentry_whereDeclared (unew)))
1816 uentry_showWhereSpecified (old);
1819 } end_globSet_allElements;
1824 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1826 if (uentry_isReallySpecified (old)
1829 message ("%s %q specified with globals list, but "
1830 "declared with no globals",
1831 ekind_capName (unew->ukind),
1832 uentry_getName (unew)),
1833 uentry_whereDeclared (unew)))
1836 (message ("Specification globals: %q",
1837 globSet_unparse (old->info->fcn->globs)),
1838 uentry_whereSpecified (old));
1842 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1843 old->info->fcn->globs);
1848 ** new modifies list must be included by old modifies list.
1850 ** file static state may be added to new, if old has internal.
1854 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1855 bool mustConform, bool completeConform)
1858 bool changedMods = FALSE;
1859 bool modInternal = FALSE;
1861 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1863 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1864 newMods = unew->info->fcn->mods;
1866 if (sRefSet_isEmpty (newMods))
1868 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1869 && uentry_isReallySpecified (old))
1873 message ("%s %q specified with modifies clause, "
1874 "but declared with no modifies clause",
1875 ekind_capName (unew->ukind),
1876 uentry_getName (unew)),
1877 uentry_whereDeclared (unew)))
1879 llgenindentmsg (message ("Specification has modifies %q",
1880 sRefSet_unparse (old->info->fcn->mods)),
1881 uentry_whereSpecified (old));
1888 sRefSet_allElements (newMods, current)
1890 if (sRef_isValid (current))
1892 sRef rb = sRef_getRootBase (current);
1894 if (sRef_isFileStatic (rb))
1898 if (!sRefSet_isSameMember (old->info->fcn->mods,
1899 sRef_makeInternalState ())
1900 && !sRefSet_isSameMember (old->info->fcn->mods,
1901 sRef_makeSpecState ()))
1904 && !uentry_isStatic (old)
1908 ("Modifies list for %q includes internal state, "
1909 "but %s without modifies internal.",
1910 uentry_getName (old),
1911 uentry_specOrDefName (old)),
1912 uentry_whereLast (unew)))
1914 uentry_showWhereSpecified (old);
1917 old->info->fcn->mods =
1918 sRefSet_insert (old->info->fcn->mods,
1919 sRef_makeInternalState ());
1924 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1930 if (sRef_canModifyVal (current, old->info->fcn->mods))
1932 int size = sRefSet_size (old->info->fcn->mods);
1934 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1937 if (sRefSet_size (old->info->fcn->mods) != size)
1948 ("Modifies list for %q contains %q, not modifiable "
1950 uentry_getName (old),
1951 sRef_unparse (current),
1952 uentry_specDeclName (old)),
1953 uentry_whereLast (unew)))
1955 uentry_showWhereSpecified (old);
1960 } end_sRefSet_allElements;
1962 if (completeConform && uentry_isReallySpecified (old))
1964 sRefSet_allElements (old->info->fcn->mods, el)
1966 if (sRef_canModify (el, newMods))
1975 ("Specification modifies clause for %q contains %q, "
1976 "not included in declaration modifies clause",
1977 uentry_getName (old),
1979 uentry_whereLast (unew)))
1981 uentry_showWhereSpecified (old);
1984 } end_sRefSet_allElements ;
1988 ** Make sure file static elements will be removed.
1993 context_recordFileModifies (old->info->fcn->mods);
1998 uentry_checkMutableType (uentry ue)
2000 ctype ct = uentry_getType (ue);
2002 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2004 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2006 voptgenerror (FLG_MUTREP,
2007 message ("Mutable abstract type %q declared without pointer "
2008 "indirection: %t (violates assignment semantics)",
2009 uentry_getName (ue), ct),
2010 uentry_whereDeclared (ue));
2015 uentry_setMutable (uentry e)
2017 llassert (uentry_isDatatype (e));
2018 e->info->datatype->mut = YES;
2022 uentry_checkIterArgs (uentry ue)
2024 bool hasYield = FALSE;
2027 llassert (uentry_isIter (ue));
2029 args = uentry_getParams (ue);
2031 uentryList_elements (args, el)
2033 sstate ds = uentry_getDefState (el);
2035 if (uentry_isYield (el))
2040 if (sstate_isUnknown (ds))
2042 uentry_setDefState (el, SS_DEFINED);
2048 } end_uentryList_elements;
2052 voptgenerror (FLG_HASYIELD,
2053 message ("Iterator %q declared with no yield parameters",
2054 uentry_getName (ue)),
2055 uentry_whereDeclared (ue));
2060 chkind_fromQual (qual qel)
2062 if (qual_isChecked (qel))
2066 else if (qual_isCheckMod (qel))
2070 else if (qual_isCheckedStrict (qel))
2072 return CH_CHECKEDSTRICT;
2074 else if (qual_isUnchecked (qel))
2076 return CH_UNCHECKED;
2081 /*@notreached@*/ return CH_UNKNOWN;
2086 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2088 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2090 if (!uentry_isRefCounted (ue))
2093 (FLG_ANNOTATIONERROR,
2094 message ("Reference counting qualifier %s used on non-reference "
2095 "counted storage: %q",
2097 uentry_unparse (ue)),
2098 uentry_whereLast (ue));
2102 alkind ak = alkind_fromQual (qel);
2104 uentry_setAliasKind (ue, ak);
2107 else if (qual_isRefCounted (qel))
2109 ctype ct = ctype_realType (uentry_getType (ue));
2112 if (ctype_isPointer (ct)
2113 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2115 /* check there is a refs field */
2116 uentryList fields = ctype_getFields (rt);
2117 uentry refs = uentry_undefined;
2119 uentryList_elements (fields, field)
2121 if (uentry_isRefsField (field))
2123 if (uentry_isValid (refs))
2126 (FLG_ANNOTATIONERROR,
2127 message ("Reference counted structure type %s has "
2128 "multiple refs fields: %q and %q",
2130 uentry_getName (refs),
2131 uentry_getName (field)),
2132 uentry_whereLast (field));
2137 } end_uentryList_elements;
2139 if (uentry_isInvalid (refs))
2143 message ("Reference counted structure type %s has "
2145 ctype_unparse (ct)),
2147 ("To count reference, the structure must have a field named "
2148 "refs of type int."),
2151 else if (!ctype_isInt (uentry_getType (refs)))
2154 (FLG_ANNOTATIONERROR,
2155 message ("Reference counted structure type %s refs field has "
2156 "type %s (should be int)", ctype_unparse (ct),
2157 ctype_unparse (uentry_getType (refs))),
2158 uentry_whereLast (refs));
2162 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2163 uentry_whereDeclared (ue));
2168 if ((ctype_isPointer (ct)
2169 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2170 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2172 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2173 uentry_whereDeclared (ue));
2178 (FLG_ANNOTATIONERROR,
2179 message ("Non-pointer to structure type %s declared with "
2180 "refcounted qualifier",
2181 ctype_unparse (ct)),
2182 uentry_whereLast (ue));
2186 else if (qual_isRefs (qel))
2188 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2190 uentry_setAliasKind (ue, AK_REFS);
2195 (FLG_ANNOTATIONERROR,
2196 message ("Refs qualifier used on non-structure field: %q",
2197 uentry_unparse (ue)),
2198 uentry_whereLast (ue));
2201 else if (qual_isAliasQual (qel))
2203 alkind ak = alkind_fromQual (qel);
2205 alkind oldak = uentry_getAliasKind (ue);
2206 ctype ut = uentry_getType (ue);
2208 if (alkind_isImplicit (ak)
2209 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2211 /* ignore the implied qualifier */
2215 if (uentry_isEitherConstant (ue))
2218 (FLG_ANNOTATIONERROR,
2219 message ("Alias qualifier %s used on constant: %q",
2220 alkind_unparse (ak), uentry_unparse (ue)),
2221 uentry_whereLast (ue));
2226 if (ctype_isFunction (ut))
2228 ut = ctype_getReturnType (ut);
2231 if (!(ctype_isVisiblySharable (ut)
2232 || ctype_isRealArray (ut)
2233 || ctype_isRealSU (ut)))
2235 if (!qual_isImplied (qel))
2238 (FLG_ANNOTATIONERROR,
2239 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2240 alkind_unparse (ak), ut, uentry_getName (ue)),
2241 uentry_whereLast (ue));
2248 if (uentry_isRefCounted (ue))
2250 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2251 || qual_isExposed (qel)
2252 || qual_isObserver (qel)))
2254 if (!qual_isImplied (qel))
2257 (FLG_ANNOTATIONERROR,
2259 ("Alias qualifier %s used on reference counted storage: %q",
2260 alkind_unparse (ak),
2261 uentry_unparse (ue)),
2262 uentry_whereLast (ue));
2270 if (qual_isRefQual (qel))
2273 (FLG_ANNOTATIONERROR,
2274 message ("Qualifier %s used on non-reference counted storage: %q",
2275 alkind_unparse (ak), uentry_unparse (ue)),
2276 uentry_whereLast (ue));
2285 uentry_setAliasKind (ue, ak);
2288 else if (qual_isNull (qel))
2290 if (uentry_isConstant (ue))
2294 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2295 uentry_whereDeclared (ue));
2299 uentry_setNullState (ue, NS_POSNULL);
2302 else if (qual_isRelNull (qel))
2304 uentry_setNullState (ue, NS_RELNULL);
2306 else if (qual_isNotNull (qel))
2308 uentry_setNullState (ue, NS_MNOTNULL);
2310 else if (qual_isAbstract (qel)
2311 || qual_isConcrete (qel))
2313 if (!uentry_isDatatype (ue))
2316 (FLG_ANNOTATIONERROR,
2317 message ("Qualifier %s used with non-datatype",
2318 qual_unparse (qel)),
2319 uentry_whereLast (ue));
2323 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2326 else if (qual_isMutable (qel))
2328 if (!uentry_isDatatype (ue))
2331 (FLG_ANNOTATIONERROR,
2332 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2333 uentry_whereLast (ue));
2337 if (!ynm_isOn (ue->info->datatype->mut))
2339 uentry_checkMutableType (ue);
2342 ue->info->datatype->mut = YES;
2345 else if (qual_isImmutable (qel))
2347 if (!uentry_isDatatype (ue))
2349 voptgenerror (FLG_ANNOTATIONERROR,
2350 message ("Qualifier %s used with non-datatype",
2351 qual_unparse (qel)),
2352 uentry_whereLast (ue));
2356 ue->info->datatype->mut = NO;
2359 else if (qual_isNullPred (qel))
2361 uentry_convertVarFunction (ue);
2363 if (uentry_isFunction (ue))
2365 ctype typ = uentry_getType (ue);
2366 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2368 if (ctype_isRealBool (rtype))
2370 uentryList pl = ctype_argsFunction (typ);
2372 if (uentryList_size (pl) == 1)
2374 ue->info->fcn->nullPred = qel;
2378 voptgenerror (FLG_ANNOTATIONERROR,
2379 message ("Qualifier %s used with function having %d "
2380 "arguments (should have 1)",
2382 uentryList_size (pl)),
2383 uentry_whereLast (ue));
2388 voptgenerror (FLG_ANNOTATIONERROR,
2389 message ("Qualifier %s used with function returning %s "
2390 "(should return bool)",
2392 ctype_unparse (rtype)),
2393 uentry_whereLast (ue));
2398 voptgenerror (FLG_ANNOTATIONERROR,
2399 message ("Qualifier %s used with non-function",
2400 qual_unparse (qel)),
2401 uentry_whereLast (ue));
2404 else if (qual_isExitQual (qel))
2406 exitkind exk = exitkind_fromQual (qel);
2408 if (uentry_isFunction (ue))
2410 if (exitkind_isKnown (ue->info->fcn->exitCode))
2412 voptgenerror (FLG_ANNOTATIONERROR,
2413 message ("Multiple exit qualifiers used on function %q: %s, %s",
2414 uentry_getName (ue),
2415 exitkind_unparse (ue->info->fcn->exitCode),
2416 exitkind_unparse (exk)),
2417 uentry_whereLast (ue));
2420 ue->info->fcn->exitCode = exk;
2424 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2426 uentry_makeVarFunction (ue);
2427 ue->info->fcn->exitCode = exk;
2431 voptgenerror (FLG_ANNOTATIONERROR,
2432 message ("Exit qualifier %s used with non-function (type %s)",
2434 ctype_unparse (uentry_getType (ue))),
2435 uentry_whereLast (ue));
2439 else if (qual_isMetaState (qel))
2441 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2443 if (annotationInfo_matchesContext (ainfo, ue))
2445 DPRINTF (("Reflecting %s on %s",
2446 annotationInfo_unparse (ainfo),
2447 uentry_unparseFull (ue)));
2449 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2450 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2451 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2456 (FLG_ANNOTATIONERROR,
2457 message ("Attribute annotation %s used in inconsistent context: %q",
2459 uentry_unparse (ue)),
2460 uentry_whereLast (ue)))
2462 /*@i! annotationInfo_showContextError (ainfo, ue); */
2468 if (qual_isCQual (qel))
2474 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2480 uentry_reflectQualifiers (uentry ue, qualList q)
2482 llassert (uentry_isValid (ue));
2484 DPRINTF (("Reflect qualifiers: %s / %s",
2485 uentry_unparseFull (ue), qualList_unparse (q)));
2487 qualList_elements (q, qel)
2489 if (qual_isStatic (qel))
2491 uentry_setStatic (ue);
2493 else if (qual_isUnused (qel))
2495 uentry_setUsed (ue, fileloc_undefined);
2497 else if (qual_isExternal (qel))
2499 fileloc_free (ue->whereDefined);
2500 ue->whereDefined = fileloc_createExternal ();
2502 else if (qual_isSef (qel))
2504 if (uentry_isVariable (ue))
2506 vkind vk = ue->info->var->kind;
2508 llassert (vk != VKREFPARAM);
2510 if (vk == VKYIELDPARAM)
2513 (FLG_ANNOTATIONERROR,
2514 message ("Qualifier sef cannot be used with %s: %q",
2515 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2516 uentry_unparse (ue)),
2517 uentry_whereLast (ue));
2519 else if (vk == VKRETPARAM)
2521 ue->info->var->kind = VKSEFRETPARAM;
2525 ue->info->var->kind = VKSEFPARAM;
2531 (FLG_ANNOTATIONERROR,
2532 message ("Qualifier sef is meaningful only on parameters: %q",
2533 uentry_unparse (ue)),
2534 uentry_whereLast (ue));
2537 else if (qual_isExtern (qel))
2539 ue->storageclass = SCEXTERN;
2541 else if (qual_isGlobalQual (qel)) /* undef, killed */
2543 DPRINTF (("Reflecting qual: %s / %s",
2544 qual_unparse (qel), uentry_unparse (ue)));
2546 if (uentry_isVariable (ue))
2548 sstate oldstate = ue->info->var->defstate;
2549 sstate defstate = sstate_fromQual (qel);
2552 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2553 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2555 defstate = SS_UNDEFKILLED;
2562 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2563 ue->info->var->defstate = defstate;
2568 (FLG_ANNOTATIONERROR,
2569 message ("Qualifier %s used on non-variable: %q",
2570 qual_unparse (qel), uentry_unparse (ue)),
2571 uentry_whereLast (ue));
2574 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2576 /* start modifications */
2577 else if( qual_isBufQualifier(qel) ) {
2578 ctype ct = ctype_realType(uentry_getType(ue));
2579 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2581 if( uentry_hasBufStateInfo(ue) ) {
2582 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2584 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2585 /* If formal func param */
2586 uentry_setNullTerminatedState(ue);
2587 uentry_setLen (ue, 1);
2588 uentry_setSize (ue, 1);
2590 sRef_setNullTerminatedState(uentry_getSref(ue));
2591 sRef_setLen (uentry_getSref(ue), 1);
2592 sRef_setSize (uentry_getSref(ue), 1);
2594 uentry_setPossiblyNullTerminatedState(ue);
2596 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2600 /* put other BufState Qualifiers here */
2602 cstring s = uentry_getName(ue);
2603 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2604 struct for identifier %s\n", s) );
2606 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2608 sRef retSref = uentry_getSref (ue);
2609 ctype retType = sRef_getType (retSref);
2611 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2612 sRef_setNullTerminatedState (retSref);
2618 message ("Qualifier %s used on non-pointer on \
2619 function return: %q", qual_unparse (qel),
2620 uentry_unparse (ue)));
2627 message ("Qualifier %s used on non-pointer: %q",
2628 qual_unparse (qel), uentry_unparse (ue)));
2630 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2632 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2634 ctype realType = ctype_realType (ue->utype);
2635 sstate defstate = sstate_fromQual (qel);
2637 if (ctype_isFunction (realType))
2639 realType = ctype_realType (ctype_getReturnType (realType));
2642 if (qual_isRelDef (qel))
2644 ; /* okay anywhere */
2648 if (!ctype_isAP (realType)
2649 && !ctype_isSU (realType)
2650 && !ctype_isUnknown (realType)
2651 && !ctype_isAbstract (ue->utype))
2654 (FLG_ANNOTATIONERROR,
2655 message ("Qualifier %s used on non-pointer or struct: %q",
2656 qual_unparse (qel), uentry_unparse (ue)),
2657 uentry_whereLast (ue));
2661 uentry_setDefState (ue, defstate);
2663 if (sRef_isStateSpecial (ue->sref)
2664 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2666 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2669 else if (qual_isYield (qel))
2671 if (uentry_isVariable (ue))
2673 ue->info->var->kind = VKYIELDPARAM;
2678 (FLG_ANNOTATIONERROR,
2679 message ("Qualifier %s used on non-iterator parameter: %q",
2680 qual_unparse (qel), uentry_unparse (ue)),
2681 uentry_whereLast (ue));
2684 else if (qual_isExQual (qel))
2686 exkind ek = exkind_fromQual (qel);
2687 ctype ut = uentry_getType (ue);
2689 DPRINTF (("Reflect ex qual: %s / %s",
2690 uentry_unparse (ue), exkind_unparse (ek)));
2692 if (ctype_isFunction (ut))
2694 ut = ctype_getReturnType (ut);
2697 if (!(ctype_isVisiblySharable (ut))
2698 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2699 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2701 if (!qual_isImplied (qel))
2703 if (ctype_isImmutableAbstract (ut)) {
2705 (FLG_REDUNDANTSHAREQUAL,
2706 message ("Qualifier %s used on unsharable storage type %t: %q",
2707 exkind_unparse (ek), ut, uentry_getName (ue)),
2708 uentry_whereLast (ue));
2711 (FLG_MISPLACEDSHAREQUAL,
2712 message ("Qualifier %s used on unsharable storage type %t: %q",
2713 exkind_unparse (ek), ut, uentry_getName (ue)),
2714 uentry_whereLast (ue));
2720 alkind ak = sRef_getAliasKind (ue->sref);
2722 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2723 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2725 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2727 if (!alkind_isTemp (ak))
2729 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2730 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2733 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2734 || alkind_isOwned (ak))
2742 message ("Exposure qualifier %s used on %s storage (should "
2743 "be dependent): %q",
2745 alkind_unparse (ak),
2746 uentry_unparse (ue)));
2750 else if (qual_isGlobCheck (qel))
2752 if (uentry_isVariable (ue))
2754 chkind ch = chkind_fromQual (qel);
2756 if (ue->info->var->checked != CH_UNKNOWN)
2758 if (ch == ue->info->var->checked)
2760 llerror (FLG_SYNTAX,
2761 message ("Redundant %s qualifier on %q",
2763 uentry_getName (ue)));
2767 llerror (FLG_SYNTAX,
2769 ("Contradictory %s and %s qualifiers on %q",
2771 checkedName (ue->info->var->checked),
2772 uentry_getName (ue)));
2776 ue->info->var->checked = ch;
2782 message ("Qualifier %s used with non-variable",
2783 qual_unparse (qel)));
2786 else if (qual_isReturned (qel))
2788 if (uentry_isVariable (ue))
2790 ue->info->var->kind = VKRETPARAM;
2794 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2795 qual_unparse (qel)));
2800 uentry_reflectOtherQualifier (ue, qel);
2803 sRef_storeState (ue->sref);
2804 } end_qualList_elements;
2808 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2812 uentry_isOnly (uentry ue)
2814 return (!uentry_isUndefined (ue)
2815 && uentry_isVariable (ue)
2816 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2820 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2822 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2823 sRef_setOrigAliasKind (ue->sref, ak);
2827 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2829 if (uentry_isVariable (ue))
2831 ue->info->var->nullstate = ns;
2834 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2838 uentry_isUnique (uentry ue)
2840 return (!uentry_isUndefined (ue)
2841 && uentry_isVariable (ue)
2842 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2846 uentry_isFileStatic (uentry ue)
2848 return (uentry_isStatic (ue)
2849 && (!uentry_isVariable (ue)
2850 || sRef_isFileStatic (uentry_getSref (ue))));
2854 uentry_isExported (uentry ue)
2856 if (uentry_isValid (ue))
2858 if (uentry_isVariable (ue))
2860 return (sRef_isRealGlobal (uentry_getSref (ue)));
2864 return !uentry_isStatic (ue);
2872 uentry_isNonLocal (uentry ue)
2874 return (uentry_isValid (ue) && uentry_isVariable (ue)
2875 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2879 uentry_isGlobalVariable (uentry ue)
2881 return (uentry_isValid (ue) && uentry_isVariable (ue)
2882 && sRef_isFileOrGlobalScope (ue->sref));
2886 uentry_isVisibleExternally (uentry ue)
2888 return (uentry_isValid (ue)
2889 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2890 || (!uentry_isStatic (ue)
2891 && (uentry_isFunction (ue)
2892 || uentry_isIter (ue)
2893 || uentry_isEndIter (ue)
2894 || uentry_isConstant (ue)
2895 || uentry_isDatatype (ue)
2896 || uentry_isAnyTag (ue)))));
2900 uentry_isPrintfLike (uentry ue)
2902 return (uentry_isFunction (ue)
2903 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2907 uentry_isScanfLike (uentry ue)
2909 return (uentry_isFunction (ue)
2910 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2914 uentry_isMessageLike (uentry ue)
2916 return (uentry_isFunction (ue)
2917 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2920 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2922 uentryList args = uentry_getParams (ue);
2924 if (!uentryList_isMissingParams (args))
2926 uentry last = uentry_undefined;
2928 uentryList_elements (args, current)
2930 if (uentry_isElipsisMarker (current))
2932 if (uentry_isUndefined (last))
2936 message ("Function %q is marked %s, but has no format "
2937 "string argument before elipsis",
2938 uentry_getName (ue),
2939 specCode_unparse (ue->info->fcn->specialCode)),
2940 uentry_whereLast (ue));
2941 ue->info->fcn->specialCode = SPC_NONE;
2945 ctype rt = ctype_realType (uentry_getType (last));
2947 if (!ctype_match (rt, ctype_string))
2951 /* wchar_t * is okay too */
2952 if (ctype_isAP (rt))
2954 ctype base = ctype_baseArrayPtr (rt);
2956 if (ctype_isArbitraryIntegral (base))
2966 message ("Function %q is marked %s, but the argument "
2967 "before the elipsis has type %s (should be char *)",
2968 uentry_getName (ue),
2969 specCode_unparse (ue->info->fcn->specialCode),
2970 ctype_unparse (uentry_getType (last))),
2971 uentry_whereLast (ue));
2973 ue->info->fcn->specialCode = SPC_NONE;
2980 } end_uentryList_elements ;
2984 message ("Function %q is marked %s, but has no elipsis parameter",
2985 uentry_getName (ue),
2986 specCode_unparse (ue->info->fcn->specialCode)),
2987 uentry_whereLast (ue));
2989 ue->info->fcn->specialCode = SPC_NONE;
2994 uentry_setPrintfLike (uentry ue)
2996 uentry_convertVarFunction (ue);
2997 llassertfatal (uentry_isFunction (ue));
2998 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2999 checkSpecialFunction (ue);
3003 uentry_setScanfLike (uentry ue)
3005 uentry_convertVarFunction (ue);
3006 llassertfatal (uentry_isFunction (ue));
3007 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3008 checkSpecialFunction (ue);
3012 uentry_setMessageLike (uentry ue)
3014 uentry_convertVarFunction (ue);
3015 llassertfatal (uentry_isFunction (ue));
3016 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3017 checkSpecialFunction (ue);
3021 uentry_isSpecialFunction (uentry ue)
3023 return (uentry_isFunction (ue)
3024 && (ue->info->fcn->specialCode != SPC_NONE));
3027 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3029 ctype ct = idDecl_getCtype (t);
3031 fileloc loc = setLocation ();
3032 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3033 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3035 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3036 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3037 uentry_implicitParamAnnots (ue);
3039 /* Parameter type [][] or [x][] is invalid */
3041 while (ctype_isFixedArray (base)) {
3042 base = ctype_baseArrayPtr (base);
3045 if (ctype_isIncompleteArray (base)) {
3046 base = ctype_baseArrayPtr (base);
3048 if (ctype_isArray (base)) {
3049 if (!uentry_hasName (ue)) {
3050 (void) optgenerror (FLG_INCOMPLETETYPE,
3051 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3053 ctype_unparse (ct)),
3054 uentry_whereLast (ue));
3056 (void) optgenerror (FLG_INCOMPLETETYPE,
3057 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3058 uentry_getName (ue),
3059 ctype_unparse (ct)),
3060 uentry_whereLast (ue));
3065 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3069 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3071 ctype ct = idDecl_getCtype (t);
3073 if (ctype_isFunction (ct))
3075 return (uentry_makeIdFunction (t));
3079 fileloc loc = setLocation ();
3080 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3082 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3084 if (!uentry_isExtern (ue))
3086 uentry_setDefined (ue, loc);
3094 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3096 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3104 /*@only@*/ /*@notnull@*/
3105 uentry uentry_makeConstantAux (cstring n, ctype t,
3106 /*@keep@*/ fileloc f, bool priv,
3107 /*@only@*/ multiVal m)
3109 uentry e = uentry_alloc ();
3112 e->uname = cstring_copy (n);
3114 e->storageclass = SCNONE;
3116 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3118 e->sref = sRef_makeConst (t);
3123 e->uses = filelocList_new ();
3124 e->isPrivate = priv;
3125 e->hasNameError = FALSE;
3127 e->info = (uinfo) dmalloc (sizeof (*e->info));
3128 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3129 e->info->uconst->access = typeIdSet_undefined;
3131 uentry_setSpecDef (e, f);
3133 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3135 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3138 uentry_setConstantValue (e, m);
3143 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3145 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
3148 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3150 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3151 idDecl_getCtype (t),
3154 llassert (fileloc_isUndefined (ue->whereDeclared));
3155 ue->whereDeclared = setLocation ();
3156 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3158 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3159 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3167 void uentry_setDefState (uentry ue, sstate defstate)
3169 if (uentry_isValid (ue))
3171 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3173 if (uentry_isVariable (ue))
3175 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3180 bool uentry_isCheckedUnknown (uentry ue)
3182 return (uentry_isVar (ue)
3183 && (ue->info->var->checked == CH_UNKNOWN));
3186 bool uentry_isCheckMod (uentry ue)
3188 return (uentry_isVar (ue)
3189 && (ue->info->var->checked == CH_CHECKMOD));
3192 bool uentry_isUnchecked (uentry ue)
3194 return (uentry_isVar (ue)
3195 && (ue->info->var->checked == CH_UNCHECKED));
3198 bool uentry_isChecked (uentry ue)
3200 return (uentry_isVar (ue)
3201 && (ue->info->var->checked == CH_CHECKED));
3204 bool uentry_isCheckedModify (uentry ue)
3206 return (uentry_isVar (ue)
3207 && (ue->info->var->checked == CH_CHECKED
3208 || ue->info->var->checked == CH_CHECKMOD
3209 || ue->info->var->checked == CH_CHECKEDSTRICT));
3212 bool uentry_isCheckedStrict (uentry ue)
3214 return (uentry_isVar (ue)
3215 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3218 void uentry_setUnchecked (uentry ue)
3220 llassert (uentry_isVar (ue));
3222 ue->info->var->checked = CH_UNCHECKED;
3225 void uentry_setChecked (uentry ue)
3227 llassert (uentry_isVar (ue));
3229 ue->info->var->checked = CH_CHECKED;
3232 void uentry_setCheckMod (uentry ue)
3234 llassert (uentry_isVar (ue));
3236 ue->info->var->checked = CH_CHECKMOD;
3239 void uentry_setCheckedStrict (uentry ue)
3241 llassert (uentry_isVar (ue));
3243 ue->info->var->checked = CH_CHECKEDSTRICT;
3246 static /*@only@*/ /*@notnull@*/
3247 uentry uentry_makeVariableAux (cstring n, ctype t,
3249 /*@exposed@*/ sRef s,
3250 bool priv, vkind kind)
3252 uentry e = uentry_alloc ();
3255 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3258 e->uname = cstring_copy (n);
3261 e->storageclass = SCNONE;
3263 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3270 e->uses = filelocList_new ();
3271 e->isPrivate = priv;
3272 e->hasNameError = FALSE;
3274 e->info = (uinfo) dmalloc (sizeof (*e->info));
3275 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3276 e->info->var->kind = kind;
3278 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3279 e->info->var->checked = CH_UNKNOWN;
3281 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3282 uentry_setSpecDef (e, f);
3283 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3285 if (ctype_isFunction (rt))
3287 rt = ctype_getReturnType (rt);
3290 if (ctype_isUA (rt))
3292 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3293 sRef_setStateFromType (e->sref, rt);
3296 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3297 e->info->var->defstate = sRef_getDefState (e->sref);
3298 e->info->var->nullstate = sRef_getNullState (e->sref);
3300 /* start modifications */
3301 /* This function sets the uentry for a pointer or array variable declaration,
3302 it allocates memory and sets the fields. We check if the type of the variable
3303 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3305 if( ctype_isArray (t) || ctype_isPointer(t)) {
3306 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3307 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3308 /*@access sRef@*/ /*i@222*/
3309 /* It probably isn't necessary to violate the abstraction here
3312 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
3315 e->info->var->bufinfo = NULL;
3317 /* end modification */
3323 uentry_isYield (uentry ue)
3325 return (uentry_isVariable (ue)
3326 && (ue->info->var->kind == VKYIELDPARAM
3327 || ue->info->var->kind == VKREFYIELDPARAM));
3331 uentry_isRefsField (uentry ue)
3333 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3336 /*@only@*/ /*@notnull@*/
3337 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3339 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3340 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3347 void uentry_makeVarFunction (uentry ue)
3354 llassert (uentry_isValid (ue));
3355 llassert (!sRef_modInFunction ());
3357 ak = sRef_getOrigAliasKind (ue->sref);
3358 ek = sRef_getOrigExKind (ue->sref);
3360 llassert (uentry_isVariable (ue));
3361 oldInfo = ue->info->var;
3363 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3366 ** expanded macro is marked used (until I write a pre-processor)
3369 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3372 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3373 ue->info->fcn->exitCode = XK_UNKNOWN;
3374 ue->info->fcn->nullPred = qual_createUnknown ();
3375 ue->info->fcn->specialCode = SPC_NONE;
3376 ue->info->fcn->access = typeIdSet_undefined;
3377 ue->info->fcn->hasGlobs = FALSE;
3378 ue->info->fcn->globs = globSet_undefined;
3379 ue->info->fcn->hasMods = FALSE;
3380 ue->info->fcn->mods = sRefSet_undefined;
3381 ue->info->fcn->specclauses = NULL;
3382 ue->info->fcn->defparams = uentryList_undefined;
3385 ue->info->fcn->preconditions = functionConstraint_undefined;
3389 ue->info->fcn->postconditions = functionConstraint_undefined;
3392 if (ctype_isFunction (ue->utype))
3394 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3398 ue->sref = sRef_makeType (ctype_unknown);
3401 if (sRef_isRefCounted (ue->sref))
3407 if (alkind_isUnknown (ak))
3409 if (exkind_isKnown (ek))
3411 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3412 ak = AK_IMPDEPENDENT;
3416 if (context_getFlag (FLG_RETIMPONLY))
3418 if (ctype_isFunction (ue->utype)
3419 && ctype_isVisiblySharable
3420 (ctype_realType (ctype_getReturnType (ue->utype))))
3422 if (uentryList_hasReturned (uentry_getParams (ue)))
3428 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3443 loc = ue->whereDeclared;
3445 sRef_setAliasKind (ue->sref, ak, loc);
3446 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3447 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3448 sRef_setExKind (ue->sref, ek, loc);
3450 if (oldInfo->kind == VKEXPMACRO)
3456 fileloc_free (ue->whereDefined);
3457 ue->whereDefined = fileloc_undefined;
3460 uvinfo_free (oldInfo);
3463 void uentry_makeConstantFunction (uentry ue)
3470 llassert (uentry_isValid (ue));
3471 llassert (!sRef_modInFunction ());
3473 ak = sRef_getOrigAliasKind (ue->sref);
3474 ek = sRef_getOrigExKind (ue->sref);
3476 llassert (uentry_isConstant (ue));
3477 oldInfo = ue->info->uconst;
3479 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3482 ** expanded macro is marked used (until I write a pre-processor)
3486 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3487 ue->info->fcn->exitCode = XK_UNKNOWN;
3488 ue->info->fcn->nullPred = qual_createUnknown ();
3489 ue->info->fcn->specialCode = SPC_NONE;
3490 ue->info->fcn->access = typeIdSet_undefined;
3491 ue->info->fcn->hasGlobs = FALSE;
3492 ue->info->fcn->globs = globSet_undefined;
3493 ue->info->fcn->hasMods = FALSE;
3494 ue->info->fcn->mods = sRefSet_undefined;
3495 ue->info->fcn->specclauses = NULL;
3496 ue->info->fcn->defparams = uentryList_undefined;
3499 ue->info->fcn->preconditions = functionConstraint_undefined;
3503 ue->info->fcn->postconditions = functionConstraint_undefined;
3507 if (ctype_isFunction (ue->utype))
3509 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3513 ue->sref = sRef_makeType (ctype_unknown);
3516 if (sRef_isRefCounted (ue->sref))
3522 if (alkind_isUnknown (ak))
3524 if (exkind_isKnown (ek))
3526 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3527 ak = AK_IMPDEPENDENT;
3531 if (context_getFlag (FLG_RETIMPONLY))
3533 if (ctype_isFunction (ue->utype)
3534 && ctype_isVisiblySharable
3535 (ctype_realType (ctype_getReturnType (ue->utype))))
3537 if (uentryList_hasReturned (uentry_getParams (ue)))
3543 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3558 loc = ue->whereDeclared;
3560 sRef_setAliasKind (ue->sref, ak, loc);
3561 sRef_setExKind (ue->sref, ek, loc);
3563 fileloc_free (ue->whereDefined);
3564 ue->whereDefined = fileloc_undefined;
3565 ucinfo_free (oldInfo);
3569 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3571 llassert (uentry_isValid (ue));
3573 if (uentry_isIter (ue))
3575 llassert (globSet_isUndefined (ue->info->iter->globs));
3576 ue->info->iter->globs = globs;
3580 uentry_convertVarFunction (ue);
3582 llassert (uentry_isFunction (ue));
3583 llassert (!ue->info->fcn->hasGlobs
3584 && globSet_isUndefined (ue->info->fcn->globs));
3586 ue->info->fcn->hasGlobs = TRUE;
3587 globSet_markImmutable (globs);
3588 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3593 /* ??? - evans 2001-09-09 not sure what's going on here...?
3594 if (globSet_hasStatic (globs))
3596 context_recordFileGlobals (globs);
3600 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3602 ue->info->fcn->hasMods = TRUE;
3606 void uentry_addAccessType (uentry ue, typeId tid)
3608 if (uentry_isFunction (ue))
3610 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3612 else if (uentry_isEitherConstant (ue))
3614 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3616 else if (uentry_isIter (ue))
3618 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3620 else if (uentry_isEndIter (ue))
3622 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3626 llbug (message ("no access for: %q", uentry_unparse (ue)));
3630 /*@only@*/ /*@notnull@*/ uentry
3631 uentry_makeFunction (cstring n, ctype t,
3633 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3634 /*@only@*/ warnClause warn,
3637 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3638 return (uentry_makeFunctionAux (n, t,
3639 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3640 : typeIdSet_single (access)),
3647 /*@notnull@*/ uentry
3648 uentry_makePrivFunction2 (cstring n, ctype t,
3650 globSet globs, sRefSet mods,
3653 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3658 /*@notnull@*/ uentry
3659 uentry_makeSpecFunction (cstring n, ctype t,
3661 /*@only@*/ globSet globs,
3662 /*@only@*/ sRefSet mods,
3665 uentry ue = uentry_makeFunctionAux (n, t, access,
3666 globs, mods, warnClause_undefined,
3669 uentry_setHasGlobs (ue);
3670 uentry_setHasMods (ue);
3672 reflectImplicitFunctionQualifiers (ue, TRUE);
3677 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3679 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3680 sRef_undefined, FALSE, VKEXPMACRO);
3682 uentry_setDefined (ue, f);
3686 /*@notnull@*/ /*@notnull@*/ uentry
3687 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3689 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3690 typeIdSet_singleOpt (access),
3691 globSet_undefined, sRefSet_undefined,
3692 warnClause_undefined,
3696 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3700 bool uentry_isForward (uentry e)
3702 if (uentry_isValid (e))
3704 ctype ct = uentry_getType (e);
3706 return (ctype_isUnknown (ct)
3707 || (ctype_isFunction (ct)
3708 && ctype_isUnknown (ctype_getReturnType (ct))));
3715 /*@notnull@*/ uentry
3716 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3718 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3719 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3723 /*@notnull@*/ uentry
3724 uentry_makeUnspecFunction (cstring n, ctype t,
3728 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3729 sRefSet_undefined, warnClause_undefined,
3732 reflectImplicitFunctionQualifiers (ue, TRUE);
3741 /* is exported for use by usymtab_interface */
3743 /*@notnull@*/ uentry
3744 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3745 fileloc f, bool priv)
3747 uentry e = uentry_alloc ();
3749 DPRINTF (("Make datatype: %s / %s",
3750 n, ctype_unparse (t)));
3752 /* e->shallowCopy = FALSE; */
3753 e->ukind = KDATATYPE;
3754 e->uname = cstring_copy (n);
3756 e->storageclass = SCNONE;
3757 e->sref = sRef_makeUnknown ();
3761 sRef_setStateFromType (e->sref, t);
3764 uentry_setSpecDef (e, f);
3766 e->warn = warnClause_undefined; /*@i634@*/
3767 e->uses = filelocList_new ();
3768 e->isPrivate = priv;
3769 e->hasNameError = FALSE;
3774 e->info = (uinfo) dmalloc (sizeof (*e->info));
3775 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3776 e->info->datatype->abs = abstract;
3777 e->info->datatype->mut = mut;
3778 e->info->datatype->type = ctype_undefined;
3780 if (uentry_isDeclared (e))
3782 uentry_setDefined (e, f);
3785 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3787 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3793 /*@notnull@*/ uentry
3794 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3796 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3799 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3801 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3802 ctype_bool, NO, abstract,
3803 fileloc_getBuiltin (),
3806 ret->info->datatype->type = ctype_bool;
3814 static /*@only@*/ /*@notnull@*/ uentry
3815 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3816 /*@only@*/ fileloc f)
3818 uentry e = uentry_alloc ();
3821 e->uname = cstring_copy (n);
3823 e->sref = sRef_makeUnknown ();
3824 e->storageclass = SCNONE;
3828 uentry_setSpecDef (e, f);
3830 e->warn = warnClause_undefined; /*@i452@*/
3831 e->uses = filelocList_new ();
3832 e->isPrivate = FALSE;
3833 e->hasNameError = FALSE;
3835 e->info = (uinfo) dmalloc (sizeof (*e->info));
3836 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3837 e->info->iter->access = access;
3838 e->info->iter->mods = sRefSet_undefined;
3839 e->info->iter->globs = globSet_undefined;
3841 uentry_checkIterArgs (e);
3845 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3847 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3850 static /*@notnull@*/ uentry
3851 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3853 uentry e = uentry_alloc ();
3855 /* e->shallowCopy = FALSE; */
3856 e->ukind = KENDITER;
3857 e->storageclass = SCNONE;
3858 e->uname = message ("end_%s", n);
3859 e->utype = ctype_unknown;
3860 e->sref = sRef_makeUnknown ();
3862 uentry_setSpecDef (e, f);
3867 e->uses = filelocList_new ();
3868 e->isPrivate = FALSE;
3869 e->hasNameError = FALSE;
3871 e->info = (uinfo) dmalloc (sizeof (*e->info));
3872 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3874 e->info->enditer->access = access;
3876 e->warn = warnClause_undefined; /*@i452@*/
3880 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3882 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3889 static /*@only@*/ /*@notnull@*/ uentry
3890 uentry_makeTagAux (cstring n, ctype t,
3891 /*@only@*/ fileloc fl,
3892 bool priv, ekind kind)
3894 uentry e = uentry_alloc ();
3896 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3898 llbuglit ("uentry_makeTagAux: not a tag type");
3902 /* e->shallowCopy = FALSE; */
3903 e->uname = cstring_copy (n);
3906 e->sref = sRef_makeUnknown ();
3907 e->storageclass = SCNONE;
3909 uentry_setSpecDef (e, fl);
3914 e->uses = filelocList_new ();
3915 e->isPrivate = priv;
3916 e->hasNameError = FALSE;
3918 e->info = (uinfo) dmalloc (sizeof (*e->info));
3919 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3920 e->info->datatype->abs = NO;
3921 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3922 e->info->datatype->type = t;
3923 e->warn = warnClause_undefined; /*@i452@*/
3925 if (uentry_isDeclared (e))
3927 uentry_setDefined (e, fl);
3933 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3935 cstring sname = makeStruct (n);
3936 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3938 cstring_free (sname);
3943 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3945 cstring sname = makeStruct (n);
3946 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3948 cstring_free (sname);
3953 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3955 cstring uname = makeUnion (n);
3956 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3958 cstring_free (uname);
3964 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3966 cstring ename = makeEnum (n);
3967 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3969 cstring_free (ename);
3975 uentry_makeUnionTagLoc (cstring n, ctype t)
3977 cstring uname = makeUnion (n);
3978 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3980 cstring_free (uname);
3985 uentry_makeEnumTagLoc (cstring n, ctype t)
3987 cstring ename = makeEnum (n);
3988 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3990 cstring_free (ename);
3995 uentry_isStructTag (uentry ue)
3997 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4001 uentry_isUnionTag (uentry ue)
4003 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4007 uentry_isEnumTag (uentry ue)
4009 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4013 uentry_isAnyTag (uentry ue)
4015 return (uentry_isStructTag (ue)
4016 || uentry_isUnionTag (ue)
4017 || uentry_isEnumTag (ue));
4020 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4022 extern void uentry_destroyMod (void)
4023 /*@globals killed emarker@*/ /*@modifies emarker@*/
4025 static bool wasDestroyed = FALSE;
4027 llassert (!wasDestroyed);
4029 if (emarker != NULL)
4031 uentry_reallyFree (emarker);
4034 wasDestroyed = TRUE;
4038 uentry_makeElipsisMarker (void)
4040 if (emarker == NULL)
4042 emarker = uentry_alloc ();
4044 emarker->ukind = KELIPSMARKER;
4045 emarker->uname = cstring_makeLiteral ("...");
4046 emarker->utype = ctype_elipsMarker;
4047 emarker->sref = sRef_undefined;
4048 emarker->storageclass = SCNONE;
4049 emarker->used = FALSE;
4050 emarker->lset = FALSE;
4051 emarker->info = NULL;
4053 uentry_setSpecDef (emarker, fileloc_undefined);
4054 emarker->uses = filelocList_new ();
4055 emarker->isPrivate = FALSE;
4056 emarker->hasNameError = FALSE;
4059 /*@ignore@*/ return (emarker); /*@end@*/
4067 uentry_equiv (uentry p1, uentry p2)
4069 if (uentry_compare (p1, p2) != 0)
4080 uentry_xcomparealpha (uentry *p1, uentry *p2)
4084 if ((res = uentry_compare (*p1, *p2)) == 0) {
4085 if ((*p1 != NULL) && (*p2 != NULL)) {
4086 res = cstring_compare ((*p1)->uname,
4095 uentry_xcompareuses (uentry *p1, uentry *p2)
4100 if (uentry_isValid (u1))
4102 if (uentry_isValid (u2))
4104 return (-1 * int_compare (filelocList_size (u1->uses),
4105 filelocList_size (u2->uses)));
4114 if (uentry_isValid (u2))
4126 uentry_compareStrict (uentry v1, uentry v2)
4128 COMPARERETURN (uentry_compare (v1, v2));
4130 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4132 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4133 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4134 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4141 uentry_compare (uentry u1, uentry u2)
4143 if (u1 == u2) return 0;
4145 if (uentry_isInvalid (u1)) return -1;
4146 if (uentry_isInvalid (u2)) return 1;
4148 INTCOMPARERETURN (u1->ukind, u2->ukind);
4149 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4150 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4151 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4157 /* bug detected by lclint:
4158 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4163 return (multiVal_compare (uentry_getConstantValue (u1),
4164 uentry_getConstantValue (u2)));
4168 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4170 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4171 uentry_accessType (u2)));
4172 return (uentryList_compareParams (uentry_getParams (u1),
4173 uentry_getParams (u2)));
4175 return (typeIdSet_compare (uentry_accessType (u1),
4176 uentry_accessType (u2)));
4179 ** Functions are never equivalent
4182 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4192 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4193 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4194 sRef_getOrigAliasKind (u2->sref)));
4195 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4196 sRef_getOrigExKind (u2->sref)));
4197 COMPARERETURN (generic_compare (u1->info->var->checked,
4198 u2->info->var->checked));
4199 COMPARERETURN (generic_compare (u1->info->var->defstate,
4200 u2->info->var->defstate));
4201 return (generic_compare (u1->info->var->nullstate,
4202 u2->info->var->nullstate));
4204 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4205 u2->info->datatype->type));
4206 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4207 u2->info->datatype->mut));
4208 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4217 ** all entries are: <type>[@<info>]*#<name>
4219 ** info depends on kind:
4223 advanceField (char **s)
4225 reader_checkChar (s, '@');
4229 advanceName (char **s)
4231 reader_checkChar (s, '#');
4235 vkind_fromInt (int i)
4237 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4239 llbuglit ("vkind_fromInt: out of range");
4246 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4247 typeIdSet access, nstate nullstate,
4248 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4250 uentry e = uentry_alloc ();
4255 e->sref = sRef_makeConst (ct);
4257 sRef_setNullState (e->sref, nullstate, loc);
4258 e->storageclass = SCNONE;
4260 if (fileloc_isSpec (loc))
4262 e->whereSpecified = loc;
4263 e->whereDeclared = fileloc_undefined;
4267 e->whereSpecified = fileloc_undefined;
4268 e->whereDeclared = loc;
4271 e->whereDefined = fileloc_undefined;
4272 e->uses = filelocList_new ();
4273 e->isPrivate = FALSE;
4274 e->hasNameError = FALSE;
4279 e->warn = warnClause_undefined; /*@i452@*/
4281 e->info = (uinfo) dmalloc (sizeof (*e->info));
4282 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4283 e->info->uconst->access = access;
4285 uentry_setConstantValue (e, m);
4286 sRef_storeState (e->sref);
4291 static /*@only@*/ uentry
4292 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4293 sstate defstate, nstate isnull, alkind aliased,
4294 exkind exp, chkind checked,
4295 /*@only@*/ fileloc loc)
4297 uentry e = uentry_alloc ();
4302 e->storageclass = SCNONE;
4304 e->sref = sRef_makeType (ct);
4305 sRef_setNullState (e->sref, isnull, loc);
4307 e->whereDefined = fileloc_undefined;
4309 if (fileloc_isSpec (loc))
4311 e->whereSpecified = loc;
4312 e->whereDeclared = fileloc_undefined;
4316 e->whereSpecified = fileloc_undefined;
4317 e->whereDeclared = loc;
4320 e->isPrivate = FALSE;
4321 e->hasNameError = FALSE;
4326 e->uses = filelocList_new ();
4327 e->warn = warnClause_undefined; /*@i452@*/
4329 e->info = (uinfo) dmalloc (sizeof (*e->info));
4330 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4331 e->info->var->kind = kind;
4332 e->info->var->checked = checked;
4333 e->info->var->defstate = defstate;
4335 sRef_setDefState (e->sref, defstate, loc);
4337 e->info->var->nullstate = sRef_getNullState (e->sref);
4339 sRef_setExKind (e->sref, exp, loc);
4340 sRef_setAliasKind (e->sref, aliased, loc);
4342 sRef_storeState (e->sref);
4344 /*DRL ADDED 9-1-2000 */
4345 e->info->var->bufinfo = NULL;
4350 static /*@only@*/ uentry
4351 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4352 ynm mut, ctype rtype, alkind ak, exkind exp,
4353 sstate defstate, nstate isnull,
4354 /*@only@*/ fileloc loc)
4356 uentry e = uentry_alloc ();
4358 e->ukind = KDATATYPE;
4359 /* e->shallowCopy = FALSE; */
4362 e->storageclass = SCNONE;
4363 e->sref = sRef_makeUnknown ();
4364 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4367 ** This is only setting null state. (I think?)
4370 if (ctype_isUA (ct))
4372 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4374 if (uentry_isValid (te))
4376 sRef_setStateFromUentry (e->sref, te);
4380 /* problem for recursive type definitions */
4384 sRef_setAliasKind (e->sref, ak, loc);
4385 sRef_setExKind (e->sref, exp, loc);
4387 sRef_setDefState (e->sref, defstate, loc);
4389 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4391 isnull = NS_ABSNULL;
4394 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4395 sRef_mergeNullState (e->sref, isnull);
4397 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4399 if (fileloc_isSpec (loc))
4401 e->whereSpecified = loc;
4402 e->whereDeclared = fileloc_undefined;
4406 e->whereSpecified = fileloc_undefined;
4407 e->whereDeclared = loc;
4410 e->isPrivate = FALSE;
4411 e->hasNameError = FALSE;
4413 e->warn = warnClause_undefined; /*@i452@*/
4417 e->uses = filelocList_new ();
4419 e->info = (uinfo) dmalloc (sizeof (*e->info));
4420 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4421 e->info->datatype->abs = abstract;
4422 e->info->datatype->mut = mut;
4423 e->info->datatype->type = rtype;
4425 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4426 sRef_storeState (e->sref);
4427 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4433 static void uentry_setHasGlobs (uentry ue)
4435 llassert (uentry_isFunction (ue));
4437 ue->info->fcn->hasGlobs = TRUE;
4440 static void uentry_setHasMods (uentry ue)
4442 llassert (uentry_isFunction (ue));
4444 ue->info->fcn->hasMods = TRUE;
4448 bool uentry_hasGlobs (uentry ue)
4450 if (uentry_isFunction (ue))
4452 return (ue->info->fcn->hasGlobs);
4458 bool uentry_hasStateClauseList (uentry ue)
4460 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4463 bool uentry_hasConditions (uentry ue)
4465 return (uentry_isFunction (ue)
4466 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4467 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4470 stateClauseList uentry_getStateClauseList (uentry ue)
4472 if (!uentry_isFunction (ue))
4474 llassert (uentry_isFunction (ue));
4475 return stateClauseList_undefined;
4478 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4479 return ue->info->fcn->specclauses;
4482 bool uentry_hasMods (uentry ue)
4484 if (uentry_isFunction (ue))
4486 return (ue->info->fcn->hasMods);
4493 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4495 bool hasGlobs, /*@only@*/ globSet globs,
4496 bool hasMods, /*@only@*/ sRefSet mods,
4497 alkind ak, exkind exp,
4498 sstate defstate, nstate isnull,
4502 /*@only@*/ stateClauseList specclauses,
4503 /*@only@*/ warnClause warnclause,
4504 /*@only@*/ fileloc loc)
4506 uentry e = uentry_alloc ();
4509 /* e->shallowCopy = FALSE; */
4513 e->storageclass = SCNONE;
4515 if (ctype_isFunction (ct))
4517 ret = ctype_getReturnType (ct);
4521 if (ctype_isKnown (ct))
4523 llbug (message ("not function: %s", ctype_unparse (ct)));
4526 ret = ctype_unknown;
4529 e->sref = sRef_makeType (ret);
4531 if (ctype_isUA (ret))
4533 sRef_setStateFromType (e->sref, ret);
4536 sRef_setDefined (e->sref, loc);
4537 sRef_setNullState (e->sref, isnull, loc);
4539 sRef_setAliasKind (e->sref, ak, loc);
4540 sRef_setExKind (e->sref, exp, loc);
4541 sRef_setDefState (e->sref, defstate, loc);
4543 e->whereSpecified = loc;
4544 e->whereDefined = fileloc_undefined;
4546 e->isPrivate = FALSE;
4547 e->hasNameError = FALSE;
4551 e->uses = filelocList_new ();
4552 e->warn = warnclause;
4554 e->info = (uinfo) dmalloc (sizeof (*e->info));
4555 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4557 e->info->fcn->exitCode = exitCode;
4558 e->info->fcn->specialCode = sCode;
4559 e->info->fcn->nullPred = nullPred;
4560 e->info->fcn->access = access;
4562 e->info->fcn->specclauses = specclauses;
4563 e->info->fcn->hasGlobs = hasGlobs;
4564 e->info->fcn->globs = globs;
4566 e->info->fcn->hasMods = hasMods;
4567 e->info->fcn->mods = mods;
4569 e->info->fcn->defparams = uentryList_undefined;
4570 e->whereDeclared = fileloc_undefined;
4572 sRef_storeState (e->sref);
4575 e->info->fcn->preconditions = NULL;
4579 e->info->fcn->postconditions = NULL;
4585 static /*@only@*/ uentry
4586 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4587 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4589 uentry e = uentry_alloc ();
4591 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4593 llbuglit ("uentry_makeTagBase: not a tag type");
4596 /* e->shallowCopy = FALSE; */
4600 e->sref = sRef_makeUnknown ();
4601 e->storageclass = SCNONE;
4603 if (fileloc_isSpec (loc))
4605 e->whereSpecified = loc;
4606 e->whereDeclared = fileloc_undefined;
4610 e->whereDeclared = loc;
4611 e->whereSpecified = fileloc_undefined;
4614 e->whereDefined = fileloc_undefined;
4616 e->isPrivate = FALSE;
4617 e->hasNameError = FALSE;
4621 e->uses = filelocList_new ();
4622 e->warn = warnClause_undefined; /*@i452@*/
4624 e->info = (uinfo) dmalloc (sizeof (*e->info));
4625 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4626 e->info->datatype->abs = NO;
4627 e->info->datatype->mut = MAYBE;
4628 e->info->datatype->type = rtype;
4630 sRef_storeState (e->sref);
4636 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4637 ctype ct, /*@only@*/ fileloc loc)
4639 uentry e = uentry_alloc ();
4641 /* e->shallowCopy = FALSE; */
4645 e->sref = sRef_makeUnknown ();
4646 e->storageclass = SCNONE;
4648 if (fileloc_isSpec (loc))
4650 e->whereSpecified = loc;
4651 e->whereDeclared = fileloc_undefined;
4655 e->whereDeclared = loc;
4656 e->whereSpecified = fileloc_undefined;
4659 e->whereDefined = fileloc_undefined;
4661 e->isPrivate = FALSE;
4662 e->hasNameError = FALSE;
4666 e->uses = filelocList_new ();
4667 e->warn = warnClause_undefined; /*@i452@*/
4669 e->info = (uinfo) dmalloc (sizeof (*e->info));
4670 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4671 e->info->iter->access = access;
4672 e->info->iter->mods = sRefSet_undefined;
4673 e->info->iter->globs = globSet_undefined;
4675 sRef_storeState (e->sref);
4680 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4681 /*@only@*/ fileloc loc)
4683 uentry e = uentry_alloc ();
4685 /* e->shallowCopy = FALSE; */
4686 e->ukind = KENDITER;
4687 e->storageclass = SCNONE;
4689 e->utype = ctype_unknown;
4690 e->sref = sRef_makeUnknown ();
4692 if (fileloc_isSpec (loc))
4694 e->whereSpecified = loc;
4695 e->whereDeclared = fileloc_undefined;
4699 e->whereDeclared = loc;
4700 e->whereSpecified = fileloc_undefined;
4703 e->whereDefined = fileloc_undefined;
4705 e->isPrivate = FALSE;
4706 e->hasNameError = FALSE;
4710 e->uses = filelocList_new ();
4711 e->warn = warnClause_undefined; /*@i452@*/
4713 e->info = (uinfo) dmalloc (sizeof (*e->info));
4714 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4715 e->info->enditer->access = access;
4716 sRef_storeState (e->sref);
4721 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4729 uentry_undump (ekind kind, fileloc loc, char **s)
4733 DPRINTF (("Uentry undump: %s", *s));
4737 reader_checkChar (s, '!');
4738 reader_checkChar (s, '.');
4739 ue = uentry_makeElipsisMarker ();
4743 ctype ct = ctype_undump (s);
4757 reader_checkChar (s, '|');
4759 if (reader_optCheckChar (s, '@'))
4761 tkind = vkind_fromInt (reader_getInt (s));
4762 reader_checkChar (s, '|');
4769 if (reader_optCheckChar (s, '$'))
4771 defstate = SS_UNKNOWN;
4772 isnull = NS_UNKNOWN;
4773 aliased = AK_IMPTEMP;
4775 checked = CH_UNKNOWN;
4777 else if (reader_optCheckChar (s, '&'))
4779 defstate = SS_DEFINED;
4780 isnull = NS_UNKNOWN;
4781 aliased = AK_IMPTEMP;
4783 checked = CH_UNKNOWN;
4785 else if (reader_optCheckChar (s, '^'))
4787 defstate = SS_UNKNOWN;
4788 isnull = NS_UNKNOWN;
4789 aliased = AK_IMPTEMP;
4791 checked = CH_UNKNOWN;
4795 defstate = sstate_fromInt (reader_getInt (s));
4796 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4797 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4799 if (reader_optCheckChar (s, '&'))
4802 checked = CH_UNKNOWN;
4806 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4807 advanceField (s); checked = (chkind) (reader_getInt (s));
4812 name = reader_getStringWord (s);
4814 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4816 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4817 isnull, aliased, exp,
4818 checked, fileloc_copy (loc));
4831 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4832 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4833 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4834 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4835 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4836 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4837 advanceField (s); rtype = ctype_undump (s);
4839 name = reader_getStringWord (s);
4840 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4841 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4842 aliased, exp, defstate, isnull,
4843 fileloc_copy (loc));
4860 stateClauseList specclauses = stateClauseList_undefined;
4861 warnClause warnclause = warnClause_undefined;
4863 if (reader_optCheckChar (s, '$'))
4865 defstate = SS_DEFINED;
4866 isnull = NS_UNKNOWN;
4867 exitCode = XK_UNKNOWN;
4869 nullPred = qual_createUnknown ();
4873 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4874 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4875 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4876 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4877 advanceField (s); nullPred = qual_undump (s);
4880 if (reader_optCheckChar (s, '$'))
4883 globs = globSet_undefined;
4885 mods = sRefSet_undefined;
4887 else if (reader_optCheckChar (s, '^'))
4890 globs = globSet_undefined;
4892 mods = sRefSet_undefined;
4896 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4897 advanceField (s); globs = globSet_undump (s);
4898 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4899 advanceField (s); mods = sRefSet_undump (s);
4902 if (reader_optCheckChar (s, '$'))
4909 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4910 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4913 advanceField (s); access = typeIdSet_undump (s);
4916 ** Optional clauses: Start with @<code>:
4919 while (reader_optCheckChar (s, '@'))
4921 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4923 reader_checkChar (s, ':');
4924 warnclause = warnClause_undump (s);
4926 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4928 reader_checkChar (s, ':');
4929 specclauses = stateClauseList_undump (s);
4937 advanceName (s); name = reader_getStringWord (s);
4939 ue = uentry_makeFunctionBase (name, ct, access,
4942 ak, exp, defstate, isnull,
4943 exitCode, specc, nullPred,
4946 fileloc_copy (loc));
4947 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4954 advanceField (s); access = typeIdSet_undump (s);
4955 advanceName (s); name = reader_getStringWord (s);
4957 ue = uentry_makeIterBase (name, access, ct,
4958 fileloc_copy (loc));
4965 advanceField (s); access = typeIdSet_undump (s);
4966 advanceName (s); name = reader_getStringWord (s);
4968 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4978 if (reader_optCheckChar (s, '$'))
4980 val = multiVal_undefined;
4981 access = typeIdSet_undefined;
4982 nullstate = NS_UNKNOWN;
4986 advanceField (s); val = multiVal_undump (s);
4987 advanceField (s); access = typeIdSet_undump (s);
4988 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4991 advanceName (s); name = reader_getStringWord (s);
4993 ue = uentry_makeConstantBase (name, ct, access,
4994 nullstate, fileloc_copy (loc), val);
5003 advanceField (s); rtype = ctype_undump (s);
5004 advanceName (s); name = reader_getStringWord (s);
5005 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5009 llcontbuglit ("uentry_undump: invalid");
5010 ue = uentry_undefined;
5013 llcontbuglit ("uentry_undump: elips marker");
5014 ue = uentry_undefined;
5023 uentry_dump (uentry v)
5025 return (uentry_dumpAux (v, FALSE));
5029 uentry_dumpParam (uentry v)
5031 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5032 ("dump: %s", uentry_unparseFull (v)));
5034 return (uentry_dumpAux (v, TRUE));
5038 uentry_dumpAux (uentry v, bool isParam)
5040 llassert (uentry_isValid (v));
5041 llassert (!uentry_isGlobalMarker (v));
5043 DPRINTF (("Dump uentry: [%p]", v));
5044 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5049 llcontbuglit ("uentry_dump: invalid entry");
5050 return cstring_undefined;
5052 return (message ("!."));
5056 vkind vk = v->info->var->kind;
5057 sstate dss = sRef_getDefState (v->sref);
5058 nstate nst = sRef_getNullState (v->sref);
5059 alkind alk = sRef_getAliasKind (v->sref);
5060 exkind exk = sRef_getExKind (v->sref);
5061 chkind chk = v->info->var->checked;
5063 DPRINTF (("Dumping var"));
5065 if (dss == SS_UNKNOWN
5066 && nst == NS_UNKNOWN
5067 && alk == AK_IMPTEMP
5068 && exk == XO_UNKNOWN
5069 && chk == CH_UNKNOWN)
5071 sdump = cstring_makeLiteral ("$");
5073 else if (dss == SS_DEFINED
5074 && nst == NS_UNKNOWN
5075 && alk == AK_IMPTEMP
5076 && exk == XO_UNKNOWN
5077 && chk == CH_UNKNOWN)
5079 sdump = cstring_makeLiteral ("&");
5081 else if (dss == SS_UNKNOWN
5082 && nst == NS_UNKNOWN
5083 && alk == AK_UNKNOWN
5084 && exk == XO_UNKNOWN
5085 && chk == CH_UNKNOWN)
5087 sdump = cstring_makeLiteral ("^");
5089 else if (exk == XO_UNKNOWN
5090 && chk == CH_UNKNOWN)
5092 sdump = message ("%d@%d@%d&",
5099 sdump = message ("%d@%d@%d@%d@%d",
5110 return (message ("%q|@%d|%q#%s",
5111 ctype_dump (v->utype),
5114 isParam ? cstring_undefined : v->uname));
5118 return (message ("%q|%q#%s",
5119 ctype_dump (v->utype),
5121 isParam ? cstring_undefined : v->uname));
5127 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5129 exkind_unparse (sRef_getExKind (v->sref)),
5130 ctype_unparse (v->utype), (int) v->utype));
5133 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5134 ctype_dump (v->utype),
5135 ynm_unparseCode (v->info->datatype->abs),
5136 ynm_unparseCode (v->info->datatype->mut),
5137 (int) sRef_getDefState (v->sref),
5138 (int) sRef_getNullState (v->sref),
5139 (int) sRef_getAliasKind (v->sref),
5140 (int) sRef_getExKind (v->sref),
5141 ctype_dump (v->info->datatype->type),
5145 cstring sdump, gdump, adump, xdump;
5146 alkind alk = sRef_getAliasKind (v->sref);
5147 exkind exk = sRef_getExKind (v->sref);
5149 if (sRef_getDefState (v->sref) == SS_DEFINED
5150 && !nstate_isKnown (sRef_getNullState (v->sref))
5151 && !exitkind_isKnown (v->info->fcn->exitCode)
5152 && v->info->fcn->specialCode == SPC_NONE
5153 && qual_isUnknown (v->info->fcn->nullPred))
5155 sdump = cstring_makeLiteral ("$");
5159 sdump = message ("@%d@%d@%d@%d@%x",
5160 (int) sRef_getDefState (v->sref),
5161 (int) sRef_getNullState (v->sref),
5162 (int) v->info->fcn->exitCode,
5163 (int) v->info->fcn->specialCode,
5164 qual_dump (v->info->fcn->nullPred));
5167 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5169 gdump = cstring_makeLiteral ("$");
5171 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5172 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5174 gdump = cstring_makeLiteral ("^");
5178 gdump = message ("@%s@%q@%s@%q",
5179 bool_dump (uentry_hasGlobs (v)),
5180 globSet_dump (uentry_getGlobs (v)),
5181 bool_dump (uentry_hasMods (v)),
5182 sRefSet_dump (uentry_getMods (v)));
5185 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5187 adump = cstring_makeLiteral ("$");
5191 adump = message ("@%d@%d", (int) alk, (int) exk);
5194 xdump = cstring_undefined;
5196 if (uentry_hasWarning (v))
5198 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5201 if (uentry_hasStateClauseList (v))
5203 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5206 return (message ("%q%q%q%q@%q%q#%s",
5207 ctype_dump (v->utype),
5211 typeIdSet_dump (uentry_accessType (v)),
5216 return (message ("%q@%q#%s",
5217 ctype_dump (v->utype),
5218 typeIdSet_dump (v->info->iter->access),
5221 return (message ("%q@%q#%s",
5222 ctype_dump (v->utype),
5223 typeIdSet_dump (uentry_accessType (v)),
5230 if (multiVal_isUnknown (uentry_getConstantValue (v))
5231 && typeIdSet_isEmpty (uentry_accessType (v))
5232 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5234 sdump = cstring_makeLiteral ("$");
5238 sdump = message ("@%q@%q@%d",
5239 multiVal_dump (uentry_getConstantValue (v)),
5240 typeIdSet_dump (uentry_accessType (v)),
5241 (int) sRef_getNullState (v->sref));
5244 return (message ("%q%q#%s",
5245 ctype_dump (v->utype),
5252 return (message ("%q@%q#%s",
5253 ctype_dump (v->utype),
5254 ctype_dump (v->info->datatype->type), v->uname));
5261 uentry_unparseAbbrev (uentry v)
5263 if (!uentry_isVariable (v))
5265 llcontbuglit ("uentry_unparseAbbrev: not variable");
5266 return uentry_unparse (v);
5269 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5273 uentry_unparse (uentry v)
5277 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5278 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5280 st = uentry_getName (v);
5282 if (cstring_isDefined (st))
5284 return (ctype_unparseDeclaration (v->utype, st));
5289 return (cstring_copy (ctype_unparse (v->utype)));
5294 uentry_unparseFull (uentry v)
5296 if (uentry_isUndefined (v))
5298 return (cstring_makeLiteral ("<undefined>"));
5304 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5305 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5306 ctype_unparse (v->utype),
5307 fileloc_unparse (uentry_whereSpecified (v)),
5308 fileloc_unparse (uentry_whereDeclared (v)),
5309 fileloc_unparse (uentry_whereDefined (v)));
5311 DPRINTF (("uentry: %s", res));
5313 if (uentry_isDatatype (v))
5315 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5318 (ctype_isDefined (v->info->datatype->type)
5319 ? v->info->datatype->type : ctype_unknown),
5320 ynm_unparse (v->info->datatype->mut),
5321 ynm_unparse (v->info->datatype->abs),
5322 sRef_unparseState (v->sref));
5324 else if (uentry_isFunction (v))
5326 res = message ("%q / sref: %q / mods: %q / "
5327 "globs: %q / clauses: %q / pre: %q / post: %q",
5329 sRef_unparseFull (v->sref),
5330 sRefSet_unparse (v->info->fcn->mods),
5331 globSet_unparse (v->info->fcn->globs),
5332 stateClauseList_unparse (v->info->fcn->specclauses),
5333 functionConstraint_unparse (v->info->fcn->preconditions),
5334 functionConstraint_unparse (v->info->fcn->postconditions));
5336 else if (uentry_isIter (v))
5338 res = message ("%q / sref: %q",
5340 sRef_unparseFull (v->sref));
5342 else if (uentry_isVariable (v))
5344 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5346 sRef_unparseFull (v->sref),
5347 (int) v->info->var->kind,
5348 (int) v->info->var->defstate,
5349 (int) v->info->var->nullstate,
5351 DPRINTF (("sref: [%p]", v->sref));
5352 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5353 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5355 else if (uentry_isConstant (v))
5357 res = message ("%q = %q",
5358 res, multiVal_unparse (uentry_getConstantValue (v)));
5362 res = message ("%q :: %q", res, uentry_unparse (v));
5369 bool uentry_hasAccessType (uentry e)
5371 if (uentry_isValid (e))
5376 return (!typeIdSet_isEmpty (e->info->iter->access));
5378 return (!typeIdSet_isEmpty (e->info->enditer->access));
5380 return (!typeIdSet_isEmpty (e->info->fcn->access));
5383 return (!typeIdSet_isEmpty (e->info->uconst->access));
5392 typeIdSet uentry_accessType (uentry e)
5394 if (uentry_isValid (e))
5399 return (e->info->iter->access);
5401 return (e->info->enditer->access);
5403 return (e->info->fcn->access);
5406 return (e->info->uconst->access);
5412 return typeIdSet_undefined;
5416 uentry_isVariable (uentry e)
5418 return (uentry_isVar (e));
5422 uentry_isSpecified (uentry e)
5424 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5428 uentry_isReallySpecified (uentry e)
5430 return (uentry_isValid (e)
5431 && fileloc_isRealSpec (e->whereSpecified));
5435 uentry_isVar (uentry e)
5437 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5441 uentry_isFakeTag (uentry e)
5443 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5447 uentry_isDatatype (uentry e)
5449 return (!uentry_isUndefined (e) &&
5450 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5451 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5455 uentry_setAbstract (uentry e)
5459 llassert (uentry_isDatatype (e)
5460 && (ynm_isMaybe (e->info->datatype->abs)));
5462 oldid = ctype_typeId (e->info->datatype->type);
5463 e->info->datatype->abs = YES;
5464 e->info->datatype->type = ctype_createAbstract (oldid);
5468 uentry_setConcrete (uentry e)
5470 llassert (uentry_isDatatype (e)
5471 && (ynm_isMaybe (e->info->datatype->abs)));
5473 e->info->datatype->abs = NO;
5477 uentry_isAbstractDatatype (uentry e)
5479 return (uentry_isDatatype (e)
5480 && (ynm_isOn (e->info->datatype->abs)));
5484 uentry_isMaybeAbstract (uentry e)
5486 return (uentry_isDatatype (e)
5487 && (ynm_isMaybe (e->info->datatype->abs)));
5491 uentry_isMutableDatatype (uentry e)
5493 bool res = uentry_isDatatype (e)
5494 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5500 uentry_isRefCountedDatatype (uentry e)
5502 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5506 uentry_isParam (uentry u)
5508 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5509 || u->info->var->kind == VKYIELDPARAM));
5513 uentry_isExpandedMacro (uentry u)
5515 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5519 uentry_isSefParam (uentry u)
5521 return (uentry_isVariable (u)
5522 && (u->info->var->kind == VKSEFPARAM
5523 || u->info->var->kind == VKREFSEFPARAM
5524 || u->info->var->kind == VKSEFRETPARAM
5525 || u->info->var->kind == VKREFSEFRETPARAM));
5529 uentry_isRefParam (uentry u)
5531 return (uentry_isVariable (u)
5532 && (u->info->var->kind == VKREFPARAM
5533 || u->info->var->kind == VKREFYIELDPARAM
5534 || u->info->var->kind == VKREFSEFPARAM
5535 || u->info->var->kind == VKREFSEFRETPARAM));
5539 uentry_isAnyParam (uentry u)
5541 return (uentry_isVariable (u)
5542 && ((u->info->var->kind == VKPARAM)
5543 || (u->info->var->kind == VKSEFPARAM)
5544 || (u->info->var->kind == VKYIELDPARAM)
5545 || (u->info->var->kind == VKRETPARAM)
5546 || (u->info->var->kind == VKSEFRETPARAM)));
5550 uentry_getDefState (uentry u)
5552 if (uentry_isValid (u))
5554 return (sRef_getDefState (u->sref));
5558 return (SS_UNKNOWN);
5563 uentry_isOut (uentry u)
5565 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5566 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5570 uentry_isPartial (uentry u)
5572 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5573 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5577 uentry_isStateSpecial (uentry u)
5579 return ((uentry_isVariable (u)
5580 && (u->info->var->defstate == SS_SPECIAL))
5581 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5584 exitkind uentry_getExitCode (uentry ue)
5586 if (uentry_isFunction (ue))
5588 return ue->info->fcn->exitCode;
5596 qual uentry_nullPred (uentry u)
5598 llassert (uentry_isRealFunction (u));
5600 if (uentry_isFunction (u))
5602 return (u->info->fcn->nullPred);
5606 return qual_createUnknown ();
5611 ** Note for variables, this is checking the declared state, not the current state.
5615 uentry_possiblyNull (uentry u)
5617 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5618 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5622 uentry_getAliasKind (uentry u)
5624 if (uentry_isValid (u))
5626 return (sRef_getAliasKind (uentry_getSref (u)));
5635 uentry_getExpKind (uentry u)
5637 if (uentry_isValid (u))
5639 return (sRef_getExKind (uentry_getSref (u)));
5648 uentry_isIter (uentry e)
5650 return (!uentry_isUndefined (e) && e->ukind == KITER);
5654 uentry_isEndIter (uentry e)
5656 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5660 uentry_isRealFunction (uentry e)
5662 return (uentry_isFunction (e) ||
5663 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5667 uentry_hasName (uentry e)
5669 if (uentry_isValid (e))
5671 cstring s = e->uname;
5673 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5674 || uentry_isFakeTag (e)));
5683 ** Returns true for fake tags.
5684 ** This is used for dumping the library
5687 bool uentry_hasRealName (uentry e)
5689 return (uentry_isValid (e)
5690 && cstring_isNonEmpty (e->uname)
5691 && !uentry_isGlobalMarker (e));
5695 /*@observer@*/ globSet
5696 uentry_getGlobs (uentry l)
5698 if (uentry_isInvalid (l))
5700 return globSet_undefined;
5703 if (l->ukind != KFCN)
5705 if (l->ukind != KITER && l->ukind != KENDITER)
5707 if (l->ukind == KVAR)
5709 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5711 ekind_unparse (l->ukind)));
5715 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5717 ekind_unparse (l->ukind)));
5720 return globSet_undefined;
5723 return l->info->fcn->globs;
5726 /*@observer@*/ sRefSet
5727 uentry_getMods (uentry l)
5729 llassert (uentry_isValid (l));
5731 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5733 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5734 return sRefSet_undefined;
5737 return l->info->fcn->mods;
5741 uentry_getKind (uentry e)
5743 llassert (uentry_isValid (e));
5748 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5750 llassert (uentry_isEitherConstant (e));
5751 return (sRef_getValue (e->sref));
5754 /*@observer@*/ uentryList
5755 uentry_getParams (uentry l)
5757 if (uentry_isInvalid (l)) return uentryList_undefined;
5764 ctype ct = l->utype;
5766 if (ctype_isFunction (ct))
5768 return (ctype_argsFunction (ct));
5772 return uentryList_undefined;
5777 ctype ct = l->utype;
5779 llassert (ctype_isFunction (ct));
5780 return (ctype_argsFunction (ct));
5787 /*@observer@*/ cstring
5788 uentry_rawName (uentry e)
5790 if (uentry_isValid (e))
5796 return cstring_undefined;
5801 uentry_getOptName (uentry e)
5803 cstring s = uentry_getName (e);
5805 if (cstring_isDefined (s))
5807 s = cstring_appendChar (s, ' ');
5814 uentry_getName (uentry e)
5816 cstring ret = cstring_undefined;
5818 if (uentry_isValid (e))
5820 if (uentry_isAnyTag (e))
5822 ret = fixTagName (e->uname);
5824 else if (uentry_isAnyParam (e))
5826 ret = cstring_copy (fixParamName (e->uname));
5830 ret = cstring_copy (e->uname);
5837 cstring uentry_observeRealName (uentry e)
5839 cstring ret = cstring_undefined;
5841 if (uentry_isValid (e))
5843 if (uentry_isAnyTag (e))
5845 if (isFakeTag (e->uname))
5847 ret = cstring_undefined;
5851 ret = plainTagName (e->uname);
5854 else if (uentry_isAnyParam (e))
5856 ret = fixParamName (e->uname);
5867 cstring uentry_getRealName (uentry e)
5869 if (uentry_isValid (e))
5871 if (uentry_isAnyTag (e))
5873 return (cstring_undefined);
5880 return cstring_undefined;
5883 ctype uentry_getType (uentry e)
5885 if (uentry_isValid (e))
5891 return ctype_unknown;
5895 fileloc uentry_whereLast (uentry e)
5899 if (uentry_isInvalid (e))
5901 return fileloc_undefined;
5904 loc = e->whereDefined;
5906 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5911 loc = uentry_whereDeclared (e);
5913 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5918 loc = uentry_whereSpecified (e);
5922 fileloc uentry_whereEither (uentry e)
5924 if (uentry_isInvalid (e)) return fileloc_undefined;
5926 if (fileloc_isDefined (e->whereDefined)
5927 && !fileloc_isExternal (e->whereDefined))
5929 return e->whereDefined;
5931 else if (fileloc_isDefined (e->whereDeclared))
5933 return e->whereDeclared;
5937 return e->whereSpecified;
5941 fileloc uentry_whereSpecified (uentry e)
5943 if (uentry_isInvalid (e)) return fileloc_undefined;
5945 return (e->whereSpecified);
5948 fileloc uentry_whereDefined (uentry e)
5950 if (uentry_isInvalid (e)) return fileloc_undefined;
5952 return (e->whereDefined);
5955 fileloc uentry_whereDeclared (uentry e)
5957 if (uentry_isInvalid (e)) return fileloc_undefined;
5959 return (e->whereDeclared);
5962 /*@observer@*/ fileloc
5963 uentry_whereEarliest (uentry e)
5965 if (uentry_isInvalid (e)) return fileloc_undefined;
5967 if (fileloc_isDefined (e->whereSpecified))
5969 return (e->whereSpecified);
5971 else if (fileloc_isDefined (e->whereDeclared))
5973 return (e->whereDeclared);
5977 return e->whereDefined;
5982 uentry_setFunctionDefined (uentry e, fileloc loc)
5984 if (uentry_isValid (e))
5986 llassert (uentry_isFunction (e));
5988 if (fileloc_isUndefined (e->whereDeclared))
5990 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5993 if (!fileloc_isDefined (e->whereDefined))
5995 e->whereDefined = fileloc_update (e->whereDefined, loc);
6001 uentry_setDeclDef (uentry e, fileloc f)
6003 uentry_setDeclared (e, f);
6005 if (!uentry_isFunction (e)
6006 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6008 uentry_setDefined (e, f);
6013 uentry_setDeclaredForce (uentry e, fileloc f)
6015 llassert (uentry_isValid (e));
6016 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6020 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6022 llassert (uentry_isValid (e));
6023 fileloc_free (e->whereDeclared);
6024 e->whereDeclared = f;
6028 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6032 llassert (uentry_isValid (e));
6033 oldloc = e->whereDeclared;
6035 if (fileloc_isDefined (oldloc))
6037 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6039 e->whereDeclared = f;
6040 fileloc_free (oldloc);
6049 e->whereDeclared = f;
6050 fileloc_free (oldloc);
6055 uentry_setDeclared (uentry e, fileloc f)
6059 llassert (uentry_isValid (e));
6060 oldloc = e->whereDeclared;
6062 if (fileloc_isDefined (oldloc))
6064 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6066 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6075 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6080 uentry_clearDefined (uentry e)
6082 if (uentry_isValid (e))
6084 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6089 uentry_setDefined (uentry e, fileloc f)
6093 llassert (uentry_isValid (e));
6094 oldloc = e->whereDefined;
6096 if (fileloc_isDefined (oldloc))
6098 if (fileloc_isLib (oldloc)
6099 || fileloc_isImport (oldloc)
6100 || fileloc_isBuiltin (oldloc)
6101 || fileloc_isPreproc (oldloc))
6103 e->whereDefined = fileloc_update (e->whereDefined, f);
6107 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6113 if (optgenerror (FLG_REDEF,
6114 message ("%s %q redefined",
6115 ekind_capName (e->ukind),
6116 uentry_getName (e)),
6119 llgenindentmsg (message ("Previous definition of %q",
6120 uentry_getName (e)),
6128 e->whereDefined = fileloc_update (e->whereDefined, f);
6133 uentry_isCodeDefined (uentry e)
6135 llassert (uentry_isValid (e));
6137 return (fileloc_isDefined (e->whereDefined));
6141 uentry_isDeclared (uentry e)
6143 if (uentry_isValid (e))
6145 return (fileloc_isDefined (e->whereDeclared));
6151 sRef uentry_getSref (uentry e)
6153 /* not true, used for functions too (but shouldn't be? */
6154 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6156 if (uentry_isInvalid (e)) return sRef_undefined;
6161 sRef uentry_getOrigSref (uentry e)
6163 /*@i523*/ /* evans 2001-09-09 - need to fix this
6164 if (uentry_isValid (e))
6166 if (uentry_isVariable (e))
6168 return e->info->var->origsref;
6172 sRef sr = sRef_copy (uentry_getSref (e));
6174 sRef_resetState (sr);
6175 sRef_clearDerived (sr);
6181 return sRef_undefined;
6185 if (uentry_isValid (e))
6187 sRef sr = sRef_copy (uentry_getSref (e));
6189 sRef_resetState (sr);
6190 sRef_clearDerived (sr);
6192 if (uentry_isVariable (e))
6194 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6195 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6202 return sRef_undefined;
6207 ** requires: uentry e is not in a hashed symbol table
6211 uentry_setName (uentry e, /*@only@*/ cstring n)
6213 llassert (uentry_isValid (e));
6215 cstring_free (e->uname);
6220 uentry_setType (uentry e, ctype t)
6222 if (uentry_isValid (e))
6225 sRef_setType (e->sref, t);
6230 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6233 ctype rettype = ctype_unknown;
6235 llassert (uentry_isValid (ue));
6237 uentry_convertVarFunction (ue);
6238 llassert (uentry_isFunction (ue));
6240 rct = ctype_realType (ue->utype);
6242 if (ctype_isFunction (rct))
6244 rettype = ctype_getReturnType (rct);
6247 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6251 uentry_setRefParam (uentry e)
6253 if (!uentry_isVar (e))
6255 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6259 if (e->info->var->kind == VKSEFPARAM)
6261 e->info->var->kind = VKREFSEFPARAM;
6263 else if (e->info->var->kind == VKSEFRETPARAM)
6265 e->info->var->kind = VKREFSEFRETPARAM;
6267 else if (e->info->var->kind == VKYIELDPARAM)
6269 e->info->var->kind = VKREFYIELDPARAM;
6273 e->info->var->kind = VKREFPARAM;
6279 uentry_setParam (uentry e)
6281 if (!uentry_isVar (e))
6283 if (uentry_isElipsisMarker (e))
6289 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6296 if (e->info->var->kind == VKYIELDPARAM
6297 || e->info->var->kind == VKSEFPARAM
6298 || e->info->var->kind == VKSEFRETPARAM)
6304 e->info->var->kind = VKPARAM;
6308 e->uname = makeParam (e->uname);
6309 cstring_free (oldname);
6314 uentry_setSref (uentry e, sRef s)
6316 if (uentry_isValid (e))
6318 if (sRef_isValid (e->sref))
6320 sRef_mergeStateQuietReverse (e->sref, s);
6324 e->sref = sRef_saveCopy (s);
6330 uentry_getAbstractType (uentry e)
6332 llassert (uentry_isDatatype (e));
6335 ** This assertion removed.
6336 ** Okay to have undefined type, for system types
6338 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6339 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6344 if (ctype_isUndefined (e->info->datatype->type))
6346 return ctype_unknown;
6350 ** Sadly, a kludge...
6353 if (ctype_isUserBool (e->info->datatype->type)) {
6357 return e->info->datatype->type;
6360 ctype uentry_getRealType (uentry e)
6363 typeId uid = USYMIDINVALID;
6365 if (uentry_isInvalid (e))
6367 return ctype_unknown;
6370 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6372 if (uentry_isAnyTag (e))
6377 if (uentry_isAbstractType (e))
6379 ct = uentry_getAbstractType (e);
6381 if (ctype_isManifestBool (ct)) {
6385 llassert (ctype_isUA (ct));
6387 uid = ctype_typeId (ct);
6389 if (!context_hasAccess (uid))
6395 ct = uentry_getType (e);
6397 /* if (ctype_isUserBool (ct)) return ct; */
6399 if (ctype_isManifestBool (ct)) {
6403 if (ctype_isUA (ct))
6405 usymId iid = ctype_typeId (ct);
6407 if (usymId_equal (iid, uid))
6409 llcontbug (message ("uentry_getRealType: recursive type! %s",
6410 ctype_unparse (ct)));
6415 /* evs 2000-07-25: possible infinite recursion ? */
6416 uentry ue2 = usymtab_getTypeEntry (iid);
6420 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6421 return ctype_unknown;
6424 return uentry_getRealType (ue2);
6433 ctype uentry_getForceRealType (uentry e)
6436 typeId uid = USYMIDINVALID;
6438 if (uentry_isInvalid (e))
6440 return ctype_unknown;
6443 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6445 if (uentry_isAnyTag (e))
6450 if (uentry_isAbstractType (e))
6452 ct = uentry_getAbstractType (e);
6453 llassert (ctype_isUA (ct));
6455 uid = ctype_typeId (ct);
6456 /* no check for access! */
6459 ct = uentry_getType (e);
6461 /* evs 2000-07-25 */
6462 /* if (ctype_isUserBool (ct)) return ct; */
6464 if (ctype_isManifestBool (ct)) {
6468 if (ctype_isUA (ct))
6470 usymId iid = ctype_typeId (ct);
6472 if (usymId_equal (iid, uid))
6474 llcontbug (message ("uentry_getRealType: recursive type! %s",
6475 ctype_unparse (ct)));
6480 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6489 uentry uentry_nameCopy (cstring name, uentry e)
6491 uentry enew = uentry_alloc ();
6493 llassert (uentry_isValid (e));
6495 /* enew->shallowCopy = FALSE; */
6496 enew->ukind = e->ukind;
6498 enew->utype = e->utype;
6499 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6500 enew->whereDefined = fileloc_copy (e->whereDefined);
6501 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6502 enew->sref = sRef_copy (e->sref);
6503 enew->used = e->used;
6505 enew->isPrivate = e->isPrivate;
6506 enew->hasNameError = FALSE;
6508 enew->uses = filelocList_new ();
6509 enew->warn = warnClause_undefined;
6511 enew->storageclass = e->storageclass;
6512 enew->info = uinfo_copy (e->info, e->ukind);
6518 uentry_setDatatype (uentry e, usymId uid)
6520 llassert (uentry_isDatatype (e));
6522 if (uentry_isAbstractType (e))
6524 e->info->datatype->type = ctype_createAbstract (uid);
6528 e->info->datatype->type = ctype_createUser (uid);
6533 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6534 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6537 llassert (uentry_isValid (e));
6539 if (fileloc_isSpec (f) || fileloc_isImport (f))
6541 e->whereSpecified = f;
6542 e->whereDeclared = fileloc_undefined;
6543 e->whereDefined = fileloc_undefined;
6547 e->whereSpecified = fileloc_undefined;
6548 e->whereDeclared = f;
6549 e->whereDefined = fileloc_undefined;
6552 llassert (fileloc_storable (f));
6556 ucinfo_free (/*@only@*/ ucinfo u)
6562 uvinfo_free (/*@only@*/ uvinfo u)
6564 /*drl7x added 6/29/01 */
6565 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6570 udinfo_free (/*@only@*/ udinfo u)
6576 ufinfo_free (/*@only@*/ ufinfo u)
6578 globSet_free (u->globs);
6579 sRefSet_free (u->mods);
6580 stateClauseList_free (u->specclauses);
6585 uiinfo_free (/*@only@*/ uiinfo u)
6591 ueinfo_free (/*@only@*/ ueinfo u)
6596 static /*@only@*/ ucinfo
6597 ucinfo_copy (ucinfo u)
6599 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6600 ret->access = u->access;
6604 static /*@only@*/ uvinfo
6605 uvinfo_copy (uvinfo u)
6607 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6609 ret->kind = u->kind;
6610 ret->nullstate = u->nullstate;
6611 ret->defstate = u->defstate;
6612 ret->checked = u->checked;
6614 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6616 /* drl added 07-02-001 */
6617 /* copy null terminated information */
6619 if (u->bufinfo != NULL)
6621 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6622 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6623 ret->bufinfo->size = u->bufinfo->size;
6624 ret->bufinfo->len = u->bufinfo->len;
6629 ret->bufinfo = NULL;
6635 static /*@only@*/ udinfo
6636 udinfo_copy (udinfo u)
6638 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6642 ret->type = u->type;
6647 static /*@only@*/ ufinfo
6648 ufinfo_copy (ufinfo u)
6650 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6652 ret->hasGlobs = u->hasGlobs;
6653 ret->hasMods = u->hasMods;
6654 ret->exitCode = u->exitCode;
6655 ret->specialCode = u->specialCode;
6656 ret->nullPred = u->nullPred;
6657 ret->access = u->access;
6658 ret->globs = globSet_newCopy (u->globs);
6659 ret->mods = sRefSet_newCopy (u->mods);
6660 ret->defparams = u->defparams;
6661 ret->specclauses = stateClauseList_copy (u->specclauses);
6663 ret->preconditions = functionConstraint_copy (u->preconditions);
6664 ret->postconditions = functionConstraint_copy (u->postconditions);
6669 static /*@only@*/ uiinfo
6670 uiinfo_copy (uiinfo u)
6672 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6674 ret->access = u->access;
6675 ret->globs = globSet_newCopy (u->globs);
6676 ret->mods = sRefSet_newCopy (u->mods);
6681 static /*@only@*/ ueinfo
6682 ueinfo_copy (ueinfo u)
6684 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6686 ret->access = u->access;
6691 uinfo_free (uinfo u, ekind kind)
6696 case KCONST: ucinfo_free (u->uconst); break;
6697 case KVAR: uvinfo_free (u->var); break;
6701 case KDATATYPE: udinfo_free (u->datatype); break;
6702 case KFCN: ufinfo_free (u->fcn); break;
6703 case KITER: uiinfo_free (u->iter); break;
6704 case KENDITER: ueinfo_free (u->enditer); break;
6705 case KELIPSMARKER: break;
6706 case KINVALID: break;
6712 static /*@only@*/ /*@null@*/ uinfo
6713 uinfo_copy (uinfo u, ekind kind)
6715 if (kind == KELIPSMARKER || kind == KINVALID)
6721 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6726 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6727 case KVAR: ret->var = uvinfo_copy (u->var); break;
6731 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6732 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6733 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6734 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6742 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6744 filelocList_free (e->uses);
6745 cstring_free (e->uname);
6747 uinfo_free (e->info, e->ukind);
6749 fileloc_free (e->whereSpecified);
6750 fileloc_free (e->whereDefined);
6751 fileloc_free (e->whereDeclared);
6753 warnClause_free (e->warn);
6759 extern void uentry_markOwned (/*@owned@*/ uentry u)
6761 sfreeEventually (u);
6765 uentry_free (/*@only@*/ uentry e)
6767 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6769 uentry_reallyFree (e);
6774 ** For uentry's in the global or file scope
6778 uentry_freeComplete (/*@only@*/ uentry e)
6780 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6782 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6783 /*@i@*/ sRef_free (e->sref);
6784 e->sref = sRef_undefined;
6785 uentry_reallyFree (e);
6790 ** requires old->kind != new->kind, old->uname = new->uname
6794 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6796 llassert (uentry_isValid (old));
6797 llassert (uentry_isValid (unew));
6799 if (uentry_isEitherConstant (unew)
6800 && (fileloc_isPreproc (uentry_whereDeclared (old))
6801 || ctype_isUnknown (old->utype))
6802 && !uentry_isSpecified (old))
6810 if (!uentry_isDeclared (old))
6812 if (uentry_isSpecified (old))
6814 if (uentry_isSpecified (unew))
6816 llbuglit ("Respecification!");
6818 else if (uentry_isDeclared (unew))
6822 message ("%s %q inconsistently declared as %s: %t",
6823 ekind_capName (old->ukind),
6824 uentry_getName (unew),
6825 ekind_unparseLong (unew->ukind),
6827 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6829 uentry_showWhereLastKind (old);
6841 message ("%s %q inconsistently declared as %s: %t",
6842 ekind_capName (old->ukind),
6843 uentry_getName (unew),
6844 ekind_unparseLong (unew->ukind),
6846 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6848 uentry_showWhereLastKind (old);
6854 llassert (uentry_isDeclared (unew));
6856 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6857 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6861 message ("%s %q inconsistently redeclared as %s",
6862 ekind_capName (old->ukind),
6863 uentry_getName (unew),
6864 ekind_unparseLong (unew->ukind)),
6865 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6867 uentry_showWhereLastKind (old);
6873 uentry_updateInto (old, unew);
6877 ** def is the definition of spec, modifies spec
6879 ** reports any inconsistencies
6880 ** returns the summary of all available information
6881 ** if spec and def are inconsistent, def is returned
6885 uentry_showWhereLast (uentry spec)
6887 if (uentry_isValid (spec))
6889 if (fileloc_isDefined (spec->whereDefined)
6890 && !fileloc_isLib (spec->whereDefined)
6891 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6893 llgenindentmsg (message ("Previous definition of %q: %t",
6894 uentry_getName (spec),
6895 uentry_getType (spec)),
6896 uentry_whereDefined (spec));
6898 else if (uentry_isDeclared (spec))
6900 llgenindentmsg (message ("Previous declaration of %q: %t",
6901 uentry_getName (spec),
6902 uentry_getType (spec)),
6903 uentry_whereDeclared (spec));
6905 else if (uentry_isSpecified (spec))
6907 if (uentry_hasName (spec))
6909 llgenindentmsg (message ("Specification of %q: %t",
6910 uentry_getName (spec),
6911 uentry_getType (spec)),
6912 uentry_whereSpecified (spec));
6916 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6917 uentry_whereSpecified (spec));
6922 /* nothing to show */
6928 uentry_showWhereLastKind (uentry spec)
6930 if (uentry_isValid (spec))
6932 if (fileloc_isDefined (spec->whereDefined)
6933 && !fileloc_isLib (spec->whereDefined)
6934 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6936 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6937 uentry_getName (spec),
6938 ekind_unparseLong (spec->ukind),
6939 uentry_getType (spec)),
6940 uentry_whereDefined (spec));
6942 else if (uentry_isDeclared (spec))
6944 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6945 uentry_getName (spec),
6946 ekind_unparseLong (spec->ukind),
6947 uentry_getType (spec)),
6948 uentry_whereDeclared (spec));
6950 else if (uentry_isSpecified (spec))
6952 if (uentry_hasName (spec))
6954 llgenindentmsg (message ("Specification of %q as %s: %t",
6955 uentry_getName (spec),
6956 ekind_unparseLong (spec->ukind),
6957 uentry_getType (spec)),
6958 uentry_whereSpecified (spec));
6962 llgenindentmsg (message ("Specification as %s: %t",
6963 ekind_unparseLong (spec->ukind),
6964 uentry_getType (spec)),
6965 uentry_whereSpecified (spec));
6970 /* nothing to show */
6976 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6978 fileloc loc = uentry_whereDefined (ce);
6980 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6982 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6986 loc = uentry_whereSpecified (ce);
6988 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6990 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6995 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6997 if (uentry_isDeclared (spec))
6999 llgenindentmsg (message ("Previous declaration of %q: %q",
7000 uentry_getName (spec), extra),
7001 uentry_whereDeclared (spec));
7003 else if (uentry_isSpecified (spec))
7005 llgenindentmsg (message ("Specification of %q: %q",
7006 uentry_getName (spec), extra),
7007 uentry_whereSpecified (spec));
7011 cstring_free (extra);
7016 uentry_showWhereDeclared (uentry spec)
7018 if (uentry_isDeclared (spec))
7020 if (uentry_hasName (spec))
7022 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7023 uentry_whereDeclared (spec));
7027 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7030 else if (uentry_isSpecified (spec))
7032 if (uentry_hasName (spec))
7034 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7035 uentry_whereSpecified (spec));
7039 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7044 /* nothing to show */
7050 uentry_showWhereAny (uentry spec)
7052 if (uentry_isDeclared (spec))
7054 if (uentry_hasName (spec))
7056 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7057 uentry_whereDeclared (spec));
7061 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7064 else if (uentry_isSpecified (spec))
7066 if (uentry_hasName (spec))
7068 llgenindentmsg (message ("Specification of %q",
7069 uentry_getName (spec)),
7070 uentry_whereSpecified (spec));
7074 llgenindentmsg (cstring_makeLiteral ("Specification"),
7075 uentry_whereSpecified (spec));
7078 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7080 if (uentry_hasName (spec))
7082 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7083 uentry_whereDefined (spec));
7087 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7092 /* nothing to show */
7097 uentry_showWhereDefined (uentry spec)
7099 if (uentry_isCodeDefined (spec))
7101 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7102 uentry_whereDefined (spec));
7107 uentry_showWhereLastPlain (uentry spec)
7109 if (uentry_isDeclared (spec))
7111 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7112 uentry_whereDeclared (spec));
7114 else if (uentry_isSpecified (spec))
7116 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7117 uentry_whereSpecified (spec));
7125 uentry_showWhereLastVal (uentry spec, cstring val)
7127 if (uentry_isDeclared (spec))
7129 llgenindentmsg (message ("Previous declaration of %q: %s",
7130 uentry_getName (spec), val),
7131 uentry_whereDeclared (spec));
7133 else if (uentry_isSpecified (spec))
7135 llgenindentmsg (message ("Specification of %q: %s",
7136 uentry_getName (spec), val),
7137 uentry_whereSpecified (spec));
7145 uentry_showWhereSpecified (uentry spec)
7147 if (uentry_isSpecified (spec))
7149 if (uentry_hasName (spec))
7151 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7152 uentry_whereSpecified (spec));
7156 llgenindentmsg (cstring_makeLiteral ("Specification"),
7157 uentry_whereSpecified (spec));
7160 else if (uentry_isDeclared (spec))
7162 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7163 uentry_whereDeclared (spec));
7167 /* nothing to show */
7172 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7174 if (uentry_isSpecified (spec))
7176 if (uentry_hasName (spec))
7178 llgenindentmsg (message ("Specification of %q: %q",
7179 uentry_getName (spec), s),
7180 uentry_whereSpecified (spec));
7184 llgenindentmsg (message ("Specification: %q", s),
7185 uentry_whereSpecified (spec));
7188 else if (uentry_isDeclared (spec))
7190 llgenindentmsg (message ("Declaration of %q: %q",
7191 uentry_getName (spec), s),
7192 uentry_whereDeclared (spec));
7196 llgenindentmsg (message ("Previous: %q", s),
7197 uentry_whereLast (spec));
7206 checkStructConformance (uentry old, uentry unew)
7209 uentryList fold, fnew;
7212 ** requires: types of old and new are structs or unions
7215 llassert (uentry_isValid (old));
7216 llassert (uentry_isValid (unew));
7218 oldr = ctype_realType (old->utype);
7219 fold = ctype_getFields (oldr);
7221 newr = ctype_realType (unew->utype);
7222 fnew = ctype_getFields (newr);
7224 if (!uentryList_matchFields (fold, fnew))
7226 if (fileloc_equal (uentry_whereLast (old),
7227 uentry_whereLast (unew)))
7235 message ("%q %q %rdeclared with fields { %q }, %s "
7236 "with fields { %q }",
7237 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7238 uentry_getName (old),
7239 uentry_isDeclared (old),
7240 uentryList_unparseAbbrev (fnew),
7241 uentry_specOrDefName (old),
7242 uentryList_unparseAbbrev (fold)),
7243 uentry_whereDeclared (unew)))
7245 uentry_showWhereLastPlain (old);
7246 uentryList_showFieldDifference (fold, fnew);
7250 old->utype = unew->utype;
7255 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7258 ** requires old and new are enums
7261 ctype rold = ctype_realType (old->utype);
7262 ctype rnew = ctype_realType (unew->utype);
7263 enumNameList eold = ctype_elist (rold);
7264 enumNameList enew = ctype_elist (rnew);
7266 if (!enumNameList_match (eold, enew))
7270 message ("Enum %q declared with members { %q } but "
7271 "specified with members { %q }",
7272 uentry_getName (old),
7273 enumNameList_unparse (enew),
7274 enumNameList_unparse (eold)),
7275 uentry_whereDeclared (unew)))
7277 uentry_showWhereSpecified (old);
7278 old->utype = unew->utype;
7284 ** either oldCurrent or newCurrent may be undefined!
7288 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7289 uentry unew, uentry newCurrent, ctype newType,
7292 bool hasError = FALSE;
7294 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7296 if (uentry_hasName (newCurrent))
7298 hasError = optgenerror
7300 message ("Parameter %d, %q, of function %q has inconsistent type: "
7301 "declared %t, %s %t",
7302 paramno + 1, uentry_getName (newCurrent),
7303 uentry_getName (unew),
7304 newType, uentry_specOrDefName (old), oldType),
7305 uentry_whereDeclared (newCurrent));
7309 hasError = optgenerror
7311 message ("Parameter %d of function %q has inconsistent type: "
7312 "declared %t, %s %t",
7313 paramno + 1, uentry_getName (unew),
7314 newType, uentry_specOrDefName (old), oldType),
7315 uentry_whereDeclared (newCurrent));
7317 DPRINTF (("type: %s / %s",
7318 ctype_unparse (newType),
7319 ctype_unparse (ctype_realType (newType))));
7324 if (uentry_isDeclared (unew))
7326 hasError = optgenerror
7328 message ("Parameter %d of function %s has inconsistent type: "
7329 "declared %t, %s %t",
7330 paramno + 1, unew->uname,
7331 newType, uentry_specOrDefName (old), oldType),
7332 uentry_whereDeclared (unew));
7336 hasError = optgenerror
7338 message ("Parameter %d of function %s has inconsistent type: "
7339 "declared %t, %s %t",
7340 paramno + 1, unew->uname,
7341 newType, uentry_specOrDefName (old), oldType),
7342 uentry_whereDeclared (unew));
7348 DPRINTF (("Here: %s / %s",
7349 uentry_unparseFull (oldCurrent),
7350 uentry_unparseFull (newCurrent)));
7352 if (!uentry_isUndefined (oldCurrent))
7354 if (!uentry_isUndefined (newCurrent)
7355 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7357 uentry_showWhereLast (oldCurrent);
7361 uentry_showWhereLastPlain (old);
7364 uentry_setType (oldCurrent, newType);
7368 uentry_showWhereLastPlain (old);
7374 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7378 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7380 uentry_isDeclared (old),
7381 uentryList_size (uentry_getParams (unew)),
7382 uentry_specOrDefName (old),
7383 uentryList_size (uentry_getParams (old))),
7384 uentry_whereDeclared (unew)))
7386 uentry_showWhereLastPlain (old);
7391 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7395 message ("Function %s inconsistently %rdeclared to return %t",
7397 uentry_isDeclared (old),
7398 ctype_getReturnType (unew->utype)),
7399 uentry_whereDeclared (unew)))
7401 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7405 static cstring paramStorageName (uentry ue)
7407 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7410 static cstring fcnErrName (uentry ue)
7412 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7415 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7417 if (uentry_isVar (ue))
7419 return (checkedName (ue->info->var->checked));
7423 return (cstring_makeLiteralTemp ("<checked invalid>"));
7427 static cstring checkedName (chkind checked)
7431 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7432 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7433 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7434 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7435 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7441 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7446 if (uentry_isVar (unew))
7448 llassert (uentry_isVar (old));
7450 oldState = old->info->var->nullstate;
7451 newState = unew->info->var->nullstate;
7455 oldState = sRef_getNullState (old->sref);
7456 newState = sRef_getNullState (unew->sref);
7459 if (oldState == NS_ABSNULL)
7461 if (uentry_isVar (old))
7463 old->info->var->nullstate = newState;
7466 sRef_mergeNullState (old->sref, newState);
7468 else if (newState == NS_UNKNOWN)
7470 if (completeConform && newState != oldState
7471 && uentry_isReallySpecified (old))
7475 message ("%s %q specified as %s, but declared without %s qualifier",
7476 ekind_capName (unew->ukind),
7477 uentry_getName (unew),
7478 nstate_unparse (oldState),
7479 nstate_unparse (oldState)),
7480 uentry_whereDeclared (unew)))
7482 uentry_showWhereSpecified (old);
7486 if (uentry_isVar (unew))
7488 unew->info->var->nullstate = oldState;
7491 sRef_mergeNullState (unew->sref, oldState);
7493 else if (newState == NS_POSNULL)
7495 if (oldState == NS_MNOTNULL
7496 && (ctype_isUA (unew->utype)
7497 || (uentry_isFunction (unew)
7498 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7500 if (uentry_isVar (unew))
7502 unew->info->var->nullstate = oldState;
7505 sRef_mergeNullState (unew->sref, oldState);
7509 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7510 || oldState == NS_UNKNOWN)
7517 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7519 uentry_ekindName (unew),
7520 uentry_getName (unew),
7521 uentry_isDeclared (old),
7523 uentry_specOrDefName (old),
7524 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7525 uentry_whereDeclared (unew)))
7527 uentry_showWhereSpecified (old);
7532 if (uentry_isVar (old))
7534 old->info->var->nullstate = newState;
7537 sRef_mergeNullState (old->sref, newState);
7540 else if (newState == NS_MNOTNULL)
7542 if (oldState != NS_MNOTNULL)
7548 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7549 "%s without notnull qualifier",
7550 uentry_ekindName (unew),
7551 uentry_getName (unew),
7552 uentry_isDeclared (old),
7554 uentry_specOrDefName (old)),
7555 uentry_whereDeclared (unew)))
7557 uentry_showWhereSpecified (old);
7561 if (uentry_isVar (old))
7563 old->info->var->nullstate = newState;
7566 sRef_mergeNullState (old->sref, newState);
7571 if (uentry_isVar (unew))
7573 unew->info->var->nullstate = oldState;
7576 sRef_mergeNullState (unew->sref, oldState);
7581 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7582 bool mustConform, bool completeConform)
7588 if (uentry_isVar (old) && uentry_isVar (unew))
7590 oldState = old->info->var->defstate;
7591 newState = unew->info->var->defstate;
7596 oldState = sRef_getDefState (old->sref);
7597 newState = sRef_getDefState (unew->sref);
7600 if (newState != oldState
7601 && newState != SS_UNKNOWN
7602 && newState != SS_DEFINED)
7608 message ("%s %q inconsistently %rdeclared %s %s %s, "
7610 uentry_ekindName (unew),
7611 uentry_getName (unew),
7612 uentry_isDeclared (old),
7614 sstate_unparse (newState),
7615 paramStorageName (unew),
7616 uentry_specOrDefName (old),
7618 sstate_unparse (oldState),
7619 paramStorageName (unew)),
7620 uentry_whereDeclared (unew)))
7622 uentry_showWhereSpecified (old);
7626 if (vars) old->info->var->defstate = newState;
7627 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7632 && (newState != oldState) && (oldState != SS_DEFINED)
7633 && uentry_isReallySpecified (old))
7637 message ("%s %q specified as %s, but declared without %s qualifier",
7638 ekind_capName (unew->ukind),
7639 uentry_getName (unew),
7640 sstate_unparse (oldState),
7641 sstate_unparse (oldState)),
7642 uentry_whereDeclared (unew)))
7644 uentry_showWhereSpecified (old);
7648 if (vars) unew->info->var->defstate = oldState;
7649 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7654 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7655 bool mustConform, bool completeConform)
7660 oldKind = sRef_getAliasKind (old->sref);
7661 newKind = sRef_getAliasKind (unew->sref);
7663 if (alkind_isImplicit (newKind)
7664 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7666 if (completeConform && !alkind_equal (newKind, oldKind)
7667 && uentry_isReallySpecified (old))
7671 message ("%s %q specified as %s, but declared without "
7672 "explicit alias qualifier",
7673 ekind_capName (unew->ukind),
7674 uentry_getName (unew),
7675 alkind_unparse (oldKind)),
7676 uentry_whereDeclared (unew)))
7678 uentry_showWhereSpecified (old);
7683 ** This really shouldn't be necessary, but it is!
7684 ** Function params (?) use new here.
7687 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7691 if (alkind_isKnown (newKind))
7693 if (!alkind_equal (oldKind, newKind))
7695 if (alkind_isKnown (oldKind))
7700 message ("%s %q inconsistently %rdeclared %s %s storage, "
7702 uentry_ekindName (unew),
7703 uentry_getName (unew),
7704 uentry_isDeclared (old),
7706 alkind_unparse (newKind),
7707 uentry_specOrDefName (old),
7708 alkind_unparse (oldKind)),
7709 uentry_whereDeclared (unew)))
7711 uentry_showWhereSpecified (old);
7713 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7714 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7715 sRef_setAliasKind (old->sref, AK_ERROR,
7716 uentry_whereDeclared (unew));
7720 sRef_setAliasKind (old->sref, newKind,
7721 uentry_whereDeclared (unew));
7726 if (!(alkind_isImplicit (newKind)))
7729 !uentry_isFunction (unew) &&
7732 message ("%s %q inconsistently %rdeclared %s %s storage, "
7733 "implicitly %s as temp storage",
7734 uentry_ekindName (unew),
7735 uentry_getName (unew),
7736 uentry_isDeclared (old),
7738 alkind_unparse (newKind),
7739 uentry_specOrDefName (old)),
7740 uentry_whereDeclared (unew)))
7742 uentry_showWhereSpecified (old);
7746 sRef_setAliasKind (old->sref, newKind,
7747 uentry_whereDeclared (unew));
7749 else /* newKind is temp or refcounted */
7756 else /* newKind unknown */
7763 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7764 bool mustConform, bool completeConform)
7769 oldKind = sRef_getExKind (old->sref);
7770 newKind = sRef_getExKind (unew->sref);
7772 if (exkind_isKnown (newKind))
7774 if (oldKind != newKind)
7776 if (exkind_isKnown (oldKind))
7781 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7782 uentry_ekindName (unew),
7783 uentry_getName (unew),
7784 uentry_isDeclared (old),
7786 exkind_unparse (newKind),
7787 uentry_specOrDefName (old),
7788 exkind_unparse (oldKind)),
7789 uentry_whereDeclared (unew)))
7791 uentry_showWhereSpecified (old);
7794 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7801 message ("%s %q inconsistently %rdeclared %s %s, "
7802 "implicitly %s without exposure qualifier",
7803 uentry_ekindName (unew),
7804 uentry_getName (unew),
7805 uentry_isDeclared (old),
7807 exkind_unparse (newKind),
7808 uentry_specOrDefName (old)),
7809 uentry_whereDeclared (unew)))
7811 uentry_showWhereSpecified (old);
7814 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7820 if (completeConform && exkind_isKnown (oldKind)
7821 && uentry_isReallySpecified (old))
7825 message ("%s %q specified as %s, but declared without "
7826 "exposure qualifier",
7827 ekind_capName (unew->ukind),
7828 uentry_getName (unew),
7829 exkind_unparse (oldKind)),
7830 uentry_whereDeclared (unew)))
7832 uentry_showWhereSpecified (old);
7836 /* yes, this is necessary! (if its a param) */
7837 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7842 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7843 bool mustConform, /*@unused@*/ bool completeConform)
7845 valueTable newvals = sRef_getValueTable (unew->sref);
7847 if (valueTable_isDefined (newvals))
7849 DPRINTF (("Check meta state: %s -> %s",
7850 uentry_unparseFull (old),
7851 uentry_unparseFull (unew)));
7853 DPRINTF (("Check meta state refs: %s -> %s",
7854 sRef_unparseFull (old->sref),
7855 sRef_unparseFull (unew->sref)));
7857 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7860 ** Copy the new values into the old ref
7863 valueTable_elements (newvals, key, newval)
7865 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7866 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7868 llassert (metaStateInfo_isDefined (msinfo));
7870 if (stateValue_isUndefined (oldval))
7872 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7876 if (stateValue_isError (oldval))
7878 if (!stateValue_isError (newval))
7880 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7884 ; /* No change necessary. */
7889 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7891 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7897 if (!stateValue_isError (newval)
7898 && !stateValue_isImplicit (newval))
7900 if (uentry_hasName (unew)
7901 || !sRef_isParam (uentry_getSref (unew)))
7906 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7907 uentry_ekindName (unew),
7908 uentry_getName (unew),
7909 uentry_isDeclared (old),
7911 stateValue_unparseValue (newval, msinfo),
7912 uentry_specOrDefName (old),
7913 stateValue_unparseValue (oldval, msinfo)),
7914 uentry_whereDeclared (unew)))
7916 uentry_showWhereSpecified (old);
7924 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7925 uentry_ekindName (unew),
7926 sRef_getParam (uentry_getSref (unew)),
7927 uentry_isDeclared (old),
7929 stateValue_unparseValue (newval, msinfo),
7930 uentry_specOrDefName (old),
7931 stateValue_unparseValue (oldval, msinfo)),
7932 uentry_whereDeclared (unew)))
7934 uentry_showWhereSpecified (old);
7940 DPRINTF (("Updating!"));
7941 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7945 DPRINTF (("Values match"));
7949 } end_valueTable_elements ;
7954 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7955 /*@notnull@*/ uentry unew,
7956 bool mustConform, bool completeConform)
7958 checkDefState (old, unew, mustConform, completeConform);
7959 checkNullState (old, unew, mustConform, completeConform);
7960 checkAliasState (old, unew, mustConform, completeConform);
7961 checkExpState (old, unew, mustConform, completeConform);
7962 checkMetaState (old, unew, mustConform, completeConform);
7964 sRef_storeState (old->sref);
7965 sRef_storeState (unew->sref);
7969 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7971 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7976 llassert (uentry_isVar (old));
7977 llassert (uentry_isVar (unew));
7979 if (cstring_isEmpty (old->uname))
7981 cstring_free (old->uname);
7982 old->uname = cstring_copy (unew->uname);
7985 if (unew->info->var->kind == VKRETPARAM
7986 || unew->info->var->kind == VKSEFRETPARAM)
7988 if (old->info->var->kind != VKRETPARAM
7989 && old->info->var->kind != VKSEFRETPARAM)
7993 message ("Parameter %q inconsistently %rdeclared as "
7994 "returned parameter",
7995 uentry_getName (unew),
7996 uentry_isDeclared (old)),
7997 uentry_whereDeclared (unew)))
7999 uentry_showWhereSpecified (old);
8000 old->info->var->kind = unew->info->var->kind;
8006 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8008 if (old->info->var->kind != VKSEFPARAM
8009 && old->info->var->kind != VKSEFRETPARAM)
8013 message ("Parameter %qinconsistently %rdeclared as "
8015 uentry_getOptName (unew),
8016 uentry_isDeclared (old)),
8017 uentry_whereDeclared (unew)))
8019 uentry_showWhereSpecified (old);
8020 old->info->var->kind = unew->info->var->kind;
8025 if (old->info->var->kind == VKSPEC)
8027 old->info->var->kind = unew->info->var->kind;
8031 unew->info->var->kind = old->info->var->kind;
8034 if (unew->info->var->checked != CH_UNKNOWN
8035 && unew->info->var->checked != old->info->var->checked)
8037 if (old->info->var->checked == CH_UNKNOWN
8038 && !fileloc_isUser (uentry_whereLast (old)))
8046 message ("Variable %q inconsistently %rdeclared as "
8047 "%s parameter (was %s)",
8048 uentry_getName (unew),
8049 uentry_isDeclared (old),
8050 checkedName (unew->info->var->checked),
8051 checkedName (old->info->var->checked)),
8052 uentry_whereDeclared (unew)))
8054 uentry_showWhereSpecified (old);
8058 old->info->var->checked = unew->info->var->checked;
8063 && (old->info->var->checked != CH_UNKNOWN)
8064 && uentry_isReallySpecified (old))
8068 message ("%s %q specified as %s, but declared without %s qualifier",
8069 ekind_capName (unew->ukind),
8070 uentry_getName (unew),
8071 checkedName (old->info->var->checked),
8072 checkedName (old->info->var->checked)),
8073 uentry_whereDeclared (unew)))
8075 uentry_showWhereSpecified (old);
8079 unew->info->var->checked = old->info->var->checked;
8082 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8085 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8087 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8092 llassert (uentry_isVar (u1));
8093 llassert (uentry_isVar (u2));
8095 if (u1->info->var->kind != u2->info->var->kind) {
8096 if (u1->info->var->kind == VKSEFRETPARAM) {
8097 if (u2->info->var->kind == VKRETPARAM) {
8100 message ("Function types are inconsistent. Parameter %d is "
8101 "sef parameter, but non-sef parameter in "
8102 "assigned function: %s",
8103 paramno, exprNode_unparse (e)),
8105 } else if (u2->info->var->kind == VKSEFPARAM) {
8108 message ("Function types are inconsistent. Parameter %d is "
8109 "returns parameter, but non-returns parameter in "
8110 "assigned function: %s",
8111 paramno, exprNode_unparse (e)),
8116 message ("Function types are inconsistent. Parameter %d is "
8117 "sef returns parameter, but non-sef returns parameter in "
8118 "assigned function: %s",
8119 paramno, exprNode_unparse (e)),
8122 } else if (u1->info->var->kind == VKRETPARAM) {
8125 message ("Function types are inconsistent. Parameter %d is "
8126 "returns parameter, but non-returns parameter in "
8127 "assigned function: %s",
8128 paramno, exprNode_unparse (e)),
8130 } else if (u1->info->var->kind == VKSEFPARAM) {
8133 message ("Function types are inconsistent. Parameter %d is "
8134 "sef parameter, but non-sef parameter in "
8135 "assigned function: %s",
8136 paramno, exprNode_unparse (e)),
8139 if (u2->info->var->kind == VKSEFRETPARAM) {
8142 message ("Function types are inconsistent. Parameter %d is "
8143 "normal parameter, but sef returns parameter in "
8144 "assigned function: %s",
8145 paramno, exprNode_unparse (e)),
8147 } else if (u2->info->var->kind == VKSEFPARAM) {
8150 message ("Function types are inconsistent. Parameter %d is "
8151 "normal parameter, but sef parameter in "
8152 "assigned function: %s",
8153 paramno, exprNode_unparse (e)),
8155 } else if (u2->info->var->kind == VKRETPARAM) {
8158 message ("Function types are inconsistent. Parameter %d is "
8159 "normal parameter, but returns parameter in "
8160 "assigned function: %s",
8161 paramno, exprNode_unparse (e)),
8169 if (u1->info->var->defstate != u2->info->var->defstate)
8173 message ("Function types are inconsistent. Parameter %d is "
8174 "%s, but %s in assigned function: %s",
8176 sstate_unparse (u1->info->var->defstate),
8177 sstate_unparse (u2->info->var->defstate),
8178 exprNode_unparse (e)),
8182 if (u1->info->var->nullstate != u2->info->var->nullstate)
8186 message ("Function types are inconsistent. Parameter %d is "
8187 "%s, but %s in assigned function: %s",
8189 nstate_unparse (u1->info->var->nullstate),
8190 nstate_unparse (u2->info->var->nullstate),
8191 exprNode_unparse (e)),
8195 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8199 message ("Function types are inconsistent. Parameter %d is "
8200 "%s, but %s in assigned function: %s",
8202 alkind_unparse (sRef_getAliasKind (u1->sref)),
8203 alkind_unparse (sRef_getAliasKind (u2->sref)),
8204 exprNode_unparse (e)),
8208 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8212 message ("Function types are inconsistent. Parameter %d is "
8213 "%s, but %s in assigned function: %s",
8215 exkind_unparse (sRef_getExKind (u1->sref)),
8216 exkind_unparse (sRef_getExKind (u2->sref)),
8217 exprNode_unparse (e)),
8223 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8224 /*@notnull@*/ uentry unew,
8225 bool mustConform, /*@unused@*/ bool completeConform)
8227 uentryList oldParams = uentry_getParams (old);
8228 uentryList newParams = uentry_getParams (unew);
8229 ctype newType = unew->utype;
8230 ctype oldType = old->utype;
8231 ctype oldRetType = ctype_unknown;
8232 ctype newRetType = ctype_unknown;
8234 DPRINTF (("Function conform: %s ==> %s",
8235 uentry_unparseFull (old),
8236 uentry_unparseFull (unew)));
8238 if (uentry_isForward (old))
8240 mustConform = FALSE;
8241 uentry_updateInto (old, unew);
8246 ** check return values
8249 if (ctype_isKnown (oldType))
8251 llassert (ctype_isFunction (oldType));
8253 oldRetType = ctype_getReturnType (oldType);
8256 if (ctype_isKnown (newType))
8258 llassert (ctype_isFunction (newType));
8260 newRetType = ctype_getReturnType (newType);
8263 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8264 && !ctype_matchDef (newRetType, oldRetType))
8266 if (mustConform) returnValueError (old, unew);
8270 if (ctype_isConj (newRetType))
8272 if (ctype_isConj (oldRetType))
8274 if (!ctype_sameAltTypes (newRetType, oldRetType))
8278 message ("Function %q inconsistently %rdeclared to "
8279 "return alternate types %s "
8280 "(types match, but alternates are not identical, "
8281 "so checking may not be correct)",
8282 uentry_getName (unew),
8283 uentry_isDeclared (old),
8284 ctype_unparse (newRetType)),
8285 uentry_whereDeclared (unew)))
8287 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8293 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8298 DPRINTF (("Before state: %s",
8299 uentry_unparseFull (old)));
8300 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8301 DPRINTF (("After state: %s",
8302 uentry_unparseFull (old)));
8304 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8306 if (exitkind_isKnown (unew->info->fcn->exitCode))
8310 message ("Function %q inconsistently %rdeclared using %s",
8311 uentry_getName (unew),
8312 uentry_isDeclared (old),
8313 exitkind_unparse (unew->info->fcn->exitCode)),
8314 uentry_whereDeclared (unew)))
8316 uentry_showWhereSpecified (old);
8321 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8325 if (!qual_isUnknown (unew->info->fcn->nullPred))
8327 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8331 message ("Function %q inconsistently %rdeclared using %s",
8332 uentry_getName (unew),
8333 uentry_isDeclared (old),
8334 qual_unparse (unew->info->fcn->nullPred)),
8335 uentry_whereDeclared (unew)))
8337 uentry_showWhereSpecified (old);
8343 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8346 if (unew->info->fcn->specialCode != SPC_NONE)
8348 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8352 message ("Function %q inconsistently %rdeclared using %s",
8353 uentry_getName (unew),
8354 uentry_isDeclared (old),
8355 specCode_unparse (unew->info->fcn->specialCode)),
8356 uentry_whereDeclared (unew)))
8358 uentry_showWhereSpecified (old);
8364 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8371 if (!uentryList_sameObject (oldParams, newParams)
8372 && (!uentryList_isMissingParams (oldParams)))
8374 if (!uentryList_isMissingParams (newParams))
8377 int nparams = uentryList_size (oldParams);
8378 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8380 if (nparams != uentryList_size (newParams))
8382 nargsError (old, unew);
8385 if (uentryList_size (newParams) < nparams)
8387 nparams = uentryList_size (newParams);
8390 while (paramno < nparams)
8392 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8393 uentry newCurrent = uentryList_getN (newParams, paramno);
8394 ctype oldCurrentType = uentry_getType (oldCurrent);
8395 ctype newCurrentType = uentry_getType (newCurrent);
8397 llassert (uentry_isValid (oldCurrent)
8398 && uentry_isValid (newCurrent));
8400 if (!uentry_isElipsisMarker (oldCurrent)
8401 && !uentry_isElipsisMarker (newCurrent))
8403 checkVarConformance (oldCurrent, newCurrent,
8404 mustConform, completeConform);
8409 if (uentry_hasName (oldCurrent)
8410 && uentry_hasName (newCurrent))
8412 cstring oldname = uentry_getName (oldCurrent);
8413 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8415 cstring nname = uentry_getName (newCurrent);
8418 if (cstring_isDefined (pfx)
8419 && cstring_equalPrefix (oldname, pfx))
8421 oname = cstring_suffix (oldname, cstring_length (pfx));
8426 /*@-branchstate@*/ } /*@=branchstate@*/
8428 if (cstring_isDefined (pfx)
8429 && cstring_equalPrefix (nname, pfx))
8431 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8436 /*@-branchstate@*/ } /*@=branchstate@*/
8438 if (!cstring_equal (oname, nnamefix))
8441 (FLG_DECLPARAMMATCH,
8442 message ("Definition parameter name %s does not match "
8443 "name of corresponding parameter in "
8446 uentry_whereLast (newCurrent)))
8448 uentry_showWhereLastPlain (oldCurrent);
8452 cstring_free (oldname);
8453 cstring_free (nname);
8457 if (!ctype_match (oldCurrentType, newCurrentType))
8459 paramTypeError (old, oldCurrent, oldCurrentType,
8460 unew, newCurrent, newCurrentType, paramno);
8464 if (ctype_isMissingParamsMarker (newCurrentType)
8465 || ctype_isElips (newCurrentType)
8466 || ctype_isMissingParamsMarker (oldCurrentType)
8467 || ctype_isElips (oldCurrentType))
8473 if (ctype_isConj (newCurrentType))
8475 if (ctype_isConj (oldCurrentType))
8477 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8481 message ("Parameter %q inconsistently %rdeclared with "
8482 "alternate types %s "
8483 "(types match, but alternates are not identical, "
8484 "so checking may not be correct)",
8485 uentry_getName (newCurrent),
8486 uentry_isDeclared (oldCurrent),
8487 ctype_unparse (newCurrentType)),
8488 uentry_whereDeclared (unew)))
8490 uentry_showWhereLastVal (oldCurrent,
8491 ctype_unparse (oldCurrentType));
8499 message ("Parameter %q inconsistently %rdeclared with "
8500 "alternate types %s",
8501 uentry_getName (newCurrent),
8502 uentry_isDeclared (oldCurrent),
8503 ctype_unparse (newCurrentType)),
8504 uentry_whereDeclared (unew)))
8506 uentry_showWhereLastVal (oldCurrent,
8507 ctype_unparse (oldCurrentType));
8514 if (ctype_isConj (oldCurrentType))
8516 uentry_setType (newCurrent, oldCurrentType);
8524 ** Forgot this! detected by lclint:
8525 ** uentry.c:1257,15: Suspected infinite loop
8531 if (!uentryList_isMissingParams (newParams))
8533 if (ctype_isConj (oldRetType))
8535 old->utype = ctype_makeFunction (oldRetType,
8536 uentryList_copy (newParams));
8540 old->utype = unew->utype;
8544 checkGlobalsConformance (old, unew, mustConform, completeConform);
8545 checkModifiesConformance (old, unew, mustConform, completeConform);
8547 DPRINTF (("Before list: %s",
8548 uentry_unparseFull (old)));
8550 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8552 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8557 message ("Function %q redeclared using special clauses (can only "
8558 "be used in first declaration)",
8559 uentry_getName (unew)),
8560 uentry_whereDeclared (unew)))
8562 uentry_showWhereLast (old);
8566 /*@i23 need checking @*/
8568 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8572 /*@i43 should be able to append? @*/
8574 stateClauseList_checkEqual (old, unew);
8575 stateClauseList_free (unew->info->fcn->specclauses);
8576 unew->info->fcn->specclauses = stateClauseList_undefined;
8579 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8582 if (fileloc_isUndefined (old->whereDeclared))
8584 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8586 else if (fileloc_isUndefined (unew->whereDeclared))
8588 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8597 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8601 llassert (uentry_isValid (ue));
8602 llassert (uentry_isEitherConstant (ue));
8604 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8605 uval = uentry_getConstantValue (ue);
8607 if (multiVal_isDefined (uval))
8609 if (multiVal_isDefined (m))
8611 if (!multiVal_equiv (uval, m))
8615 message ("%s %q defined with inconsistent value: %q",
8616 ekind_capName (ue->ukind),
8617 uentry_getName (ue),
8618 multiVal_unparse (m)),
8621 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8629 uentry_setConstantValue (ue, m);
8634 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8637 bool typeError = FALSE;
8639 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8641 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8645 DPRINTF (("Check struct conformance: %s / %s",
8646 uentry_unparseFull (old),
8647 uentry_unparseFull (unew)));
8648 checkStructConformance (old, unew);
8653 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8655 llbug (message ("struct tags: bad types: %t / %t",
8656 old->utype, unew->utype));
8660 else if (uentry_isEnumTag (old))
8662 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8664 if (mustConform) checkEnumConformance (old, unew);
8668 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8670 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8671 ctype_unparse (unew->utype)));
8675 else if (!ctype_match (old->utype, unew->utype))
8677 DPRINTF (("Type mismatch: %s / %s",
8678 ctype_unparse (old->utype),
8679 ctype_unparse (unew->utype)));
8681 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8683 ctype realt = ctype_realType (unew->utype);
8685 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8687 unew->utype = ctype_bool;
8693 typeError = optgenerror
8695 message ("%q defined as %s", uentry_getName (old),
8696 ctype_unparse (realt)),
8697 uentry_whereDeclared (unew));
8705 ctype oldr = ctype_realType (old->utype);
8706 ctype newr = ctype_realType (unew->utype);
8708 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8710 checkStructConformance (old, unew);
8712 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8714 checkStructConformance (old, unew);
8716 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8718 checkEnumConformance (old, unew);
8720 else if (uentry_isConstant (old)
8721 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8723 /* okay...for now! (should check the type is reset later... */
8727 DPRINTF (("YABA!"));
8730 message ("%s %q %rdeclared with inconsistent type: %t",
8731 ekind_capName (unew->ukind),
8732 uentry_getName (unew),
8733 uentry_isDeclared (old),
8735 uentry_whereDeclared (unew)))
8737 uentry_showWhereLast (old);
8753 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8754 /*@notnull@*/ uentry unew,
8755 bool mustConform, bool completeConform)
8757 if (ctype_isDefined (unew->info->datatype->type))
8760 ** bool is hard coded here, since it is built into LCL.
8761 ** For now, we're stuck with LCL's types.
8764 if (ctype_isDirectBool (old->utype) &&
8765 cstring_equalLit (unew->uname, "bool"))
8767 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8768 evs 2000-07-25: removed
8770 unew->utype = ctype_bool;
8773 if (ctype_isUnknown (old->info->datatype->type))
8775 old->info->datatype->type = unew->info->datatype->type;
8779 DPRINTF (("Old: %s / New: %s",
8780 uentry_unparseFull (old),
8781 uentry_unparseFull (unew)));
8782 DPRINTF (("Types: %s / %s",
8783 ctype_unparse (old->info->datatype->type),
8784 ctype_unparse (unew->info->datatype->type)));
8786 if (ctype_matchDef (old->info->datatype->type,
8787 unew->info->datatype->type))
8796 ("Type %q %s with inconsistent type: %t",
8797 uentry_getName (unew),
8798 uentry_reDefDecl (old, unew),
8799 unew->info->datatype->type),
8800 uentry_whereDeclared (unew)))
8802 uentry_showWhereLastExtra
8803 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8806 old->info->datatype->type = unew->info->datatype->type;
8811 if (unew->info->datatype->abs != MAYBE)
8813 if (ynm_isOff (old->info->datatype->abs)
8814 && ynm_isOn (unew->info->datatype->abs))
8816 if (!ctype_isDirectBool (old->utype))
8821 ("Datatype %q inconsistently %rdeclared as abstract type",
8822 uentry_getName (unew),
8823 uentry_isDeclared (old)),
8824 uentry_whereDeclared (unew)))
8826 uentry_showWhereLastPlain (old);
8830 else if (ynm_isOn (old->info->datatype->abs)
8831 && ynm_isOff (unew->info->datatype->abs))
8833 if (!ctype_isDirectBool (old->utype))
8838 ("Datatype %q inconsistently %rdeclared as concrete type",
8839 uentry_getName (unew),
8840 uentry_isDeclared (old)),
8841 uentry_whereDeclared (unew)))
8843 uentry_showWhereLastPlain (old);
8854 if (ynm_isOn (old->info->datatype->abs))
8856 old->sref = unew->sref;
8857 unew->info->datatype->mut = old->info->datatype->mut;
8860 && uentry_isReallySpecified (old))
8865 ("Datatype %q specified as abstract, "
8866 "but abstract annotation not used in declaration",
8867 uentry_getName (unew)),
8868 uentry_whereDeclared (unew)))
8870 uentry_showWhereLastPlain (old);
8876 unew->info->datatype->abs = old->info->datatype->abs;
8878 if (ynm_isMaybe (unew->info->datatype->mut))
8880 if (completeConform && ynm_isOff (old->info->datatype->mut)
8881 && uentry_isReallySpecified (old))
8886 ("Datatype %q specified as immutable, "
8887 "but immutable annotation not used in declaration",
8888 uentry_getName (unew)),
8889 uentry_whereDeclared (unew)))
8891 uentry_showWhereLastPlain (old);
8895 unew->info->datatype->mut = old->info->datatype->mut;
8897 else if (ynm_isMaybe (old->info->datatype->mut))
8899 old->info->datatype->mut = unew->info->datatype->mut;
8903 if (ynm_isOn (old->info->datatype->abs))
8905 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8909 message ("Datatype %q inconsistently %rdeclared as immutable",
8910 uentry_getName (unew),
8911 uentry_isDeclared (old)),
8912 uentry_whereDeclared (unew)))
8914 uentry_showWhereLastPlain (old);
8919 if (ynm_isOff (old->info->datatype->mut)
8920 && ynm_isOn (unew->info->datatype->mut))
8924 message ("Datatype %q inconsistently %rdeclared as mutable",
8925 uentry_getName (unew),
8926 uentry_isDeclared (old)),
8927 uentry_whereDeclared (unew)))
8929 uentry_showWhereLastPlain (old);
8934 old->info->datatype->mut = unew->info->datatype->mut;
8937 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8941 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8942 /*@notnull@*/ uentry unew,
8944 /*@unused@*/ bool completeConform)
8946 multiVal oldval = uentry_getConstantValue (old);
8947 multiVal newval = uentry_getConstantValue (unew);
8949 if (multiVal_isDefined (oldval))
8951 if (multiVal_isDefined (newval))
8953 if (!multiVal_equiv (oldval, newval))
8958 message ("%s %q %rdeclared with inconsistent value: %q",
8959 ekind_capName (unew->ukind),
8960 uentry_getName (unew),
8961 uentry_isDeclared (old),
8962 multiVal_unparse (newval)),
8963 uentry_whereDeclared (unew)))
8965 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8969 uentry_setConstantValue (unew, multiVal_copy (oldval));
8978 uentry_setConstantValue (old, multiVal_copy (newval));
8983 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8984 /*@notnull@*/ uentry unew, bool mustConform,
8985 bool completeConform)
8987 bool typeError = FALSE;
8988 bool fcnConformance = FALSE;
8990 if (!ekind_equal (unew->ukind, old->ukind))
8993 ** okay, only if one is a function and the other is
8994 ** a variable of type function.
8997 if (unew->ukind == KENUMCONST
8998 && old->ukind == KCONST)
9000 old->ukind = KENUMCONST;
9004 if (unew->ukind == KFCN
9005 && old->ukind == KCONST
9006 && ctype_isUnknown (old->utype))
9009 ** When a function is defined with an unparam macro
9012 uentry_updateInto (old, unew);
9016 if (uentry_isExpandedMacro (old)
9017 && uentry_isEitherConstant (unew))
9019 uentry_updateInto (old, unew);
9023 if (uentry_isEndIter (unew))
9025 if (ctype_isUnknown (old->utype))
9027 if (!uentry_isSpecified (old)
9028 && uentry_isCodeDefined (unew))
9030 if (!fileloc_withinLines (uentry_whereDefined (old),
9031 uentry_whereDeclared (unew), 2))
9032 { /* bogus! will give errors if there is too much whitespace */
9036 ("Iterator finalized name %q does not match name in "
9037 "previous iter declaration (should be end_%q). This iter "
9038 "is declared at %q",
9039 uentry_getName (unew),
9040 uentry_getName (old),
9041 fileloc_unparse (uentry_whereDefined (old))),
9042 uentry_whereDeclared (old));
9046 uentry_updateInto (old, unew);
9051 KindConformanceError (old, unew, mustConform);
9055 if (uentry_isFunction (unew))
9057 if (uentry_isVariable (old))
9059 if (!ctype_isUnknown (old->utype))
9061 if (ctype_isFunction (old->utype))
9063 uentry_makeVarFunction (old);
9064 checkFunctionConformance (old, unew, mustConform,
9066 fcnConformance = TRUE;
9070 KindConformanceError (old, unew, mustConform);
9075 if (uentry_isExpandedMacro (old))
9077 if (fileloc_isUndefined (unew->whereDefined))
9079 unew->whereDefined = fileloc_update (unew->whereDefined,
9083 uentry_updateInto (old, unew);
9084 old->used = unew->used = TRUE;
9089 /* undeclared identifier */
9090 old->utype = unew->utype;
9091 uentry_makeVarFunction (old);
9092 checkFunctionConformance (old, unew, FALSE, FALSE);
9093 fcnConformance = TRUE;
9099 KindConformanceError (old, unew, mustConform);
9102 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9104 if (!ctype_isUnknown (unew->utype))
9106 if (ctype_isFunction (unew->utype))
9108 uentry_makeVarFunction (unew);
9109 checkFunctionConformance (old, unew, mustConform, completeConform);
9110 fcnConformance = TRUE;
9114 KindConformanceError (old, unew, mustConform);
9119 KindConformanceError (old, unew, mustConform);
9124 KindConformanceError (old, unew, mustConform);
9130 ** check parameter lists for functions
9131 ** (before type errors, to get better messages
9134 if (uentry_isFunction (old))
9136 checkFunctionConformance (old, unew, mustConform, completeConform);
9137 fcnConformance = TRUE;
9141 if (!ctype_isUndefined (old->utype))
9143 typeError = checkTypeConformance (old, unew, mustConform);
9150 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9152 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9155 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9157 DPRINTF (("Check datatype: %s / %s",
9158 uentry_unparseFull (old),
9159 uentry_unparseFull (unew)));
9161 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9164 if (uentry_isVariable (old) && uentry_isVariable (unew))
9167 !ctype_matchDef (old->utype, unew->utype))
9172 ("Variable %q %s with inconsistent type (arrays and pointers are "
9173 "not identical in variable declarations): %t",
9174 uentry_getName (unew),
9175 uentry_reDefDecl (old, unew),
9177 uentry_whereDeclared (unew)))
9179 uentry_showWhereLast (old);
9182 ** Avoid repeated errors.
9185 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9187 old->whereDefined = fileloc_update (old->whereDefined,
9195 checkVarConformance (old, unew, mustConform, completeConform);
9200 /* old->utype = unew->utype; */
9204 if (ctype_isConj (old->utype))
9206 if (ctype_isConj (unew->utype))
9208 if (!ctype_sameAltTypes (old->utype, unew->utype))
9212 message ("%s %q inconsistently %rdeclared with "
9213 "alternate types %s "
9214 "(types match, but alternates are not identical, "
9215 "so checking may not be correct)",
9216 ekind_capName (uentry_getKind (old)),
9217 uentry_getName (unew),
9218 uentry_isDeclared (old),
9219 ctype_unparse (unew->utype)),
9220 uentry_whereDeclared (unew)))
9222 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9226 old->utype = unew->utype;
9233 if (ctype_isUnknown (old->utype))
9235 old->utype = unew->utype;
9240 if (unew->ukind == old->ukind)
9243 unew->info = uinfo_copy (old->info, old->ukind);
9246 sRef_storeState (old->sref);
9247 sRef_storeState (unew->sref);
9250 static void uentry_mergeConstraints (uentry spec, uentry def)
9252 if (uentry_isFunction (def))
9254 DPRINTF (("Here: %s / %s",
9255 uentry_unparseFull (spec),
9256 uentry_unparseFull (def)));
9257 /* evans 2001-07-21 */
9258 llassert (uentry_isFunction (spec));
9260 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9262 if (fileloc_isXHFile (uentry_whereLast (def)))
9264 llassert (uentry_isFunction (spec));
9265 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9266 def->info->fcn->preconditions);
9268 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9274 /* Check if the constraints are identical */
9279 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9280 uentry_getName (spec),
9281 functionConstraint_unparse (spec->info->fcn->preconditions)),
9282 uentry_whereLast (def)))
9284 uentry_showWhereSpecified (spec);
9287 functionConstraint_free (spec->info->fcn->preconditions);
9288 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9291 def->info->fcn->preconditions = functionConstraint_undefined;
9294 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9296 if (fileloc_isXHFile (uentry_whereLast (def)))
9298 llassert (uentry_isFunction (spec));
9299 DPRINTF (("Post: %s /++/ %s",
9300 functionConstraint_unparse (spec->info->fcn->postconditions),
9301 functionConstraint_unparse (def->info->fcn->postconditions)));
9302 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9303 def->info->fcn->postconditions);
9304 def->info->fcn->postconditions = functionConstraint_undefined;
9305 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9312 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9313 uentry_getName (spec),
9314 functionConstraint_unparse (spec->info->fcn->postconditions)),
9315 uentry_whereLast (def)))
9317 uentry_showWhereSpecified (spec);
9320 functionConstraint_free (spec->info->fcn->postconditions);
9321 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9322 def->info->fcn->postconditions = functionConstraint_undefined;
9329 ** modifies spec to reflect def, reports any inconsistencies
9333 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9335 llassert (uentry_isValid (spec));
9336 llassert (uentry_isValid (def));
9337 llassert (cstring_equal (spec->uname, def->uname));
9339 if (uentry_isFunction (def))
9341 if (uentry_isConstant (spec))
9343 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9344 uentry_makeConstantFunction (spec);
9348 uentry_convertVarFunction (spec);
9351 llassert (uentry_isFunction (spec));
9354 DPRINTF (("Merge entries: %s / %s",
9355 uentry_unparseFull (spec),
9356 uentry_unparseFull (def)));
9358 uentry_mergeConstraints (spec, def);
9360 uentry_checkConformance (spec, def, TRUE,
9361 context_getFlag (FLG_NEEDSPEC));
9363 DPRINTF (("Merge entries after conform: %s / %s",
9364 uentry_unparseFull (spec),
9365 uentry_unparseFull (def)));
9367 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9370 ** okay, declarations conform. Propagate extra information.
9373 uentry_setDefined (spec, uentry_whereDefined (def));
9374 uentry_setDeclared (spec, uentry_whereDeclared (def));
9376 if (uentry_isStatic (def))
9380 message ("%s %q specified, but declared as static",
9381 ekind_capName (def->ukind),
9382 uentry_getName (def)),
9383 uentry_whereDeclared (def)))
9385 uentry_showWhereSpecified (spec);
9390 spec->storageclass = def->storageclass;
9393 sRef_storeState (spec->sref);
9395 spec->used = def->used || spec->used;
9396 spec->hasNameError |= def->hasNameError;
9400 if (!spec->hasNameError)
9402 uentry_checkName (spec);
9411 ** Can't generate function redeclaration errors when the
9412 ** entries are merged, since we don't yet know if its the
9413 ** definition of the function.
9417 uentry_clearDecl (void)
9419 posRedeclared = uentry_undefined;
9420 fileloc_free (posLoc);
9421 posLoc = fileloc_undefined;
9425 uentry_checkDecl (void)
9427 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9429 llassert (fileloc_isDefined (posLoc));
9431 if (uentry_isCodeDefined (posRedeclared))
9433 if (optgenerror (FLG_REDECL,
9434 message ("%s %q declared after definition",
9435 ekind_capName (posRedeclared->ukind),
9436 uentry_getName (posRedeclared)),
9439 llgenindentmsg (message ("Definition of %q",
9440 uentry_getName (posRedeclared)),
9441 posRedeclared->whereDeclared);
9446 if (optgenerror (FLG_REDECL,
9447 message ("%s %q declared more than once",
9448 ekind_capName (posRedeclared->ukind),
9449 uentry_getName (posRedeclared)),
9452 llgenindentmsg (message ("Previous declaration of %q",
9453 uentry_getName (posRedeclared)),
9454 posRedeclared->whereDeclared);
9459 fileloc_free (posLoc);
9460 posLoc = fileloc_undefined;
9461 posRedeclared = uentry_undefined;
9465 ** Redefinition of old as unew.
9466 ** modifies old to reflect unew, reports any inconsistencies
9470 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9472 fileloc olddef = uentry_whereDeclared (old);
9473 fileloc unewdef = uentry_whereDeclared (unew);
9477 DPRINTF (("uentry merge: %s / %s",
9478 uentry_unparseFull (old),
9479 uentry_unparseFull (unew)));
9482 fileloc_isUndefined (olddef)
9483 && fileloc_isDefined (uentry_whereDefined (old))
9484 && !uentry_isExpandedMacro (old);
9486 if (!context_getFlag (FLG_INCONDEFSLIB)
9487 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9489 mustConform = FALSE;
9496 llassert (uentry_isValid (old));
9497 llassert (uentry_isValid (unew));
9498 llassert (cstring_equal (old->uname, unew->uname));
9500 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9502 if (uentry_isConstant (old))
9504 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9505 uentry_makeConstantFunction (old);
9509 uentry_convertVarFunction (old);
9512 llassert (uentry_isFunction (old));
9515 DPRINTF (("uentry merge: %s / %s",
9516 uentry_unparseFull (old),
9517 uentry_unparseFull (unew)));
9519 if (uentry_isExtern (unew))
9521 uentry_setUsed (old, unewdef);
9525 ** should check old one was extern!
9528 if (uentry_isStatic (old))
9530 if (!(uentry_isStatic (unew)))
9534 message ("%s %q shadows static declaration",
9535 ekind_capName (unew->ukind),
9536 uentry_getName (unew)),
9539 uentry_showWhereLast (old);
9544 uentry_setDeclDef (old, unewdef);
9547 else if (uentry_isStatic (unew))
9549 uentry_setDeclDef (old, unewdef);
9551 else if (uentry_isExtern (old))
9553 uentry_setDeclared (old, unewdef);
9557 if (!uentry_isExtern (unew)
9558 && !uentry_isForward (old)
9559 && !fileloc_equal (olddef, unewdef)
9560 && !fileloc_isUndefined (olddef)
9561 && !fileloc_isUndefined (unewdef)
9562 && !fileloc_isBuiltin (olddef)
9563 && !fileloc_isBuiltin (unewdef)
9564 && !uentry_isYield (old)
9565 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9567 if (uentry_isVariable (old) || uentry_isVariable (unew))
9569 ; /* will report redeclaration error later */
9573 if (fileloc_isDefined (uentry_whereDefined (old)))
9577 message ("%s %q defined more than once",
9578 ekind_capName (unew->ukind),
9579 uentry_getName (unew)),
9580 uentry_whereLast (unew)))
9583 (message ("Previous definition of %q",
9584 uentry_getName (old)),
9585 uentry_whereLast (old));
9588 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9590 uentry_updateInto (old, unew);
9591 old->sref = sRef_saveCopy (old->sref);
9599 if (fileloc_isLib (olddef)
9600 || fileloc_isUndefined (olddef)
9601 || fileloc_isImport (olddef))
9603 if (uentry_isExtern (unew))
9605 if (uentry_isExtern (old)
9606 || (fileloc_isDefined (uentry_whereDeclared (old))
9607 && (!fileloc_equal (uentry_whereDeclared (old),
9608 uentry_whereDefined (old)))))
9612 message ("%s %q declared more than once",
9613 ekind_capName (unew->ukind),
9614 uentry_getName (unew)),
9615 unew->whereDeclared))
9618 (message ("Previous declaration of %q",
9619 uentry_getName (old)),
9620 old->whereDeclared);
9624 uentry_setExtern (old);
9628 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9634 DPRINTF (("uentry merge: %s / %s",
9635 uentry_unparseFull (old),
9636 uentry_unparseFull (unew)));
9638 uentry_mergeConstraints (old, unew);
9639 DPRINTF (("uentry merge: %s / %s",
9640 uentry_unparseFull (old),
9641 uentry_unparseFull (unew)));
9643 uentry_checkConformance (old, unew, mustConform, FALSE);
9644 DPRINTF (("uentry merge: %s / %s",
9645 uentry_unparseFull (old),
9646 uentry_unparseFull (unew)));
9648 old->used = old->used || unew->used;
9649 old->uses = filelocList_append (old->uses, unew->uses);
9650 unew->uses = filelocList_undefined;
9652 sRef_storeState (old->sref);
9653 sRef_storeState (unew->sref);
9657 old->whereDefined = fileloc_update (old->whereDefined,
9661 DPRINTF (("here: %s", uentry_unparseFull (old)));
9664 ** No redeclaration errors for functions here, since we
9665 ** don't know if this is the definition of the function.
9668 if (fileloc_isUser (old->whereDeclared)
9669 && fileloc_isUser (unew->whereDeclared)
9670 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9671 && !fileloc_isDefined (unew->whereDefined))
9673 if (uentry_isFunction (old))
9675 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9676 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9680 if (optgenerror (FLG_REDECL,
9681 message ("%s %q declared more than once",
9682 ekind_capName (unew->ukind),
9683 uentry_getName (unew)),
9684 unew->whereDeclared))
9686 llgenindentmsg (message ("Previous declaration of %q",
9687 uentry_getName (old)),
9688 old->whereDeclared);
9693 if (fileloc_isUndefined (old->whereDefined))
9695 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9699 if (!context_processingMacros ()
9700 && fileloc_isUser (old->whereDefined)
9701 && fileloc_isUser (unew->whereDefined)
9702 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9704 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9706 if (uentry_isVariable (unew)
9707 && uentry_isExtern (unew))
9709 if (optgenerror (FLG_REDECL,
9710 message ("%s %q declared after definition",
9711 ekind_capName (unew->ukind),
9712 uentry_getName (unew)),
9713 unew->whereDeclared))
9715 llgenindentmsg (message ("Definition of %q",
9716 uentry_getName (old)),
9722 if (optgenerror (FLG_REDEF,
9723 message ("%s %q redefined",
9724 ekind_capName (unew->ukind),
9725 uentry_getName (unew)),
9726 unew->whereDefined))
9728 llgenindentmsg (message ("Previous definition of %q",
9729 uentry_getName (old)),
9737 if (uentry_isExternal (unew))
9739 old->whereDefined = fileloc_createExternal ();
9742 if (unew->hasNameError)
9744 old->hasNameError = TRUE;
9749 if (!old->hasNameError)
9751 uentry_checkName (old);
9754 DPRINTF (("After: %s", uentry_unparseFull (old)));
9755 llassert (!ctype_isUndefined (old->utype));
9759 uentry_copyState (uentry res, uentry other)
9761 llassert (uentry_isValid (res));
9762 llassert (uentry_isValid (other));
9764 res->used = other->used;
9766 res->info->var->kind = other->info->var->kind;
9767 res->info->var->defstate = other->info->var->defstate;
9768 res->info->var->nullstate = other->info->var->nullstate;
9769 res->info->var->checked = other->info->var->checked;
9771 sRef_copyState (res->sref, other->sref);
9775 uentry_sameKind (uentry u1, uentry u2)
9777 if (uentry_isValid (u1) && uentry_isValid (u2))
9779 if (uentry_isVar (u1) && uentry_isVar (u2))
9781 ctype c1 = u1->utype;
9782 ctype c2 = u2->utype;
9784 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9787 ** both functions, or both not functions
9790 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9794 return ((u1->ukind == u2->ukind));
9801 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9803 ekind okind = unew->ukind;
9804 llassert (uentry_isValid (unew));
9805 llassert (uentry_isValid (old));
9807 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9809 unew->ukind = old->ukind;
9810 llassert (cstring_equal (unew->uname, old->uname));
9811 unew->utype = old->utype;
9813 if (fileloc_isDefined (unew->whereSpecified)
9814 && !fileloc_isDefined (old->whereSpecified))
9816 ; /* Keep the old value */
9820 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9821 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9824 if (fileloc_isDefined (unew->whereDefined)
9825 && !fileloc_isDefined (old->whereDefined))
9827 ; /* Keep the old value */
9831 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9832 unew->whereDefined = fileloc_copy (old->whereDefined);
9835 if (fileloc_isDefined (unew->whereDeclared)
9836 && !fileloc_isDefined (old->whereDeclared))
9838 ; /* Keep the old value */
9842 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9843 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9846 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9848 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9849 unew->used = old->used;
9851 unew->isPrivate = old->isPrivate;
9852 unew->hasNameError = old->hasNameError;
9853 unew->uses = filelocList_append (unew->uses, old->uses);
9854 old->uses = filelocList_undefined;
9856 unew->storageclass = old->storageclass;
9857 uinfo_free (unew->info, okind);
9858 unew->info = uinfo_copy (old->info, old->ukind);
9863 uentry_copy (uentry e)
9865 if (uentry_isValid (e))
9867 uentry enew = uentry_alloc ();
9868 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9869 enew->ukind = e->ukind;
9870 enew->uname = cstring_copy (e->uname);
9871 enew->utype = e->utype;
9873 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9874 enew->whereDefined = fileloc_copy (e->whereDefined);
9875 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9877 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9878 enew->used = e->used;
9880 enew->isPrivate = e->isPrivate;
9881 enew->hasNameError = e->hasNameError;
9882 enew->uses = filelocList_undefined;
9884 enew->storageclass = e->storageclass;
9885 enew->info = uinfo_copy (e->info, e->ukind);
9886 enew->warn = warnClause_copy (e->warn);
9888 DPRINTF (("Here we are..."));
9889 DPRINTF (("original: %s", uentry_unparseFull (e)));
9890 DPRINTF (("copy: %s", uentry_unparse (enew)));
9891 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9896 return uentry_undefined;
9901 uentry_setState (uentry res, uentry other)
9903 llassert (uentry_isValid (res));
9904 llassert (uentry_isValid (other));
9906 llassert (res->ukind == other->ukind);
9907 llassert (res->ukind == KVAR);
9909 res->sref = sRef_saveCopy (other->sref);
9910 res->used = other->used;
9911 filelocList_free (res->uses);
9912 res->uses = other->uses;
9913 other->uses = filelocList_undefined;
9914 res->lset = other->lset;
9918 uentry_mergeUses (uentry res, uentry other)
9920 llassert (uentry_isValid (res));
9921 llassert (uentry_isValid (other));
9923 res->used = other->used || res->used;
9924 res->lset = other->lset || res->lset;
9925 res->uses = filelocList_append (res->uses, other->uses);
9926 other->uses = filelocList_undefined;
9931 ** This is a really ugly routine.
9933 ** gack...fix this one day.
9938 ** >> res is the false branch, other is the true branch (or continuation)
9940 ** >> res is the true branch, other is the false branch (or continutation)
9947 ** References not effected by res are propagated from other.
9951 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9952 bool flip, clause cl, fileloc loc)
9956 message ("%s %q is %s %s, but %s %s.",
9957 ekind_capName (res->ukind), uentry_getName (res),
9958 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9959 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9962 if (sRef_isDead (res->sref))
9964 sRef_showStateInfo (res->sref);
9966 else if (sRef_isKept (res->sref))
9968 sRef_showAliasInfo (res->sref);
9970 else /* dependent */
9972 sRef_showAliasInfo (res->sref);
9973 sRef_showAliasInfo (other->sref);
9976 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9980 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
9982 alkind rk = sRef_getAliasKind (rs);
9983 alkind ok = sRef_getAliasKind (os);
9985 if (alkind_isError (rk) || alkind_isError (ok))
9991 return ((sRef_isDead (rs)
9992 || (alkind_isKept (rk) && !alkind_isKept (ok))
9993 || (alkind_isDependent (rk)
9994 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9995 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10000 branchStateAltError (/*@notnull@*/ uentry res,
10001 /*@notnull@*/ uentry other, bool flip,
10002 clause cl, fileloc loc)
10006 message ("%s %q is %s %s, but %s %s.",
10007 ekind_capName (res->ukind), uentry_getName (res),
10008 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10009 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10012 if (sRef_isDead (other->sref))
10014 sRef_showStateInfo (other->sref);
10018 sRef_showAliasInfo (other->sref);
10021 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10022 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10024 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10025 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10030 ** A reference is relevant for certain checks, only if it
10031 ** is not definitely null on this path (but not declared
10032 ** to always be null.)
10035 static bool uentry_relevantReference (sRef sr, bool flip)
10037 if (sRef_isKept (sr) || sRef_isDependent (sr))
10045 return !sRef_definitelyNullContext (sr);
10049 return !sRef_definitelyNullAltContext (sr);
10055 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
10056 bool mustReturn, bool flip, bool opt,
10059 sRef rs = res->sref;
10060 sRef os = other->sref;
10062 DPRINTF (("Merge alias states: %s / %s",
10063 uentry_unparseFull (res),
10064 uentry_unparseFull (other)));
10066 if (sRef_isValid (rs))
10070 if (uentry_incompatibleMemoryStates (rs, os))
10072 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10073 sRef_unparseFull (rs), sRef_unparseFull (os)));
10075 if (sRef_isThroughArrayFetch (rs)
10076 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10078 if (sRef_isKept (rs) || sRef_isKept (os))
10080 sRef_maybeKill (rs, loc);
10082 else if (sRef_isPossiblyDead (os))
10084 sRef_maybeKill (rs, loc);
10093 if (uentry_relevantReference (os, flip))
10095 if (sRef_isLocalParamVar (rs)
10096 && (sRef_isLocalState (os)
10097 || sRef_isDependent (os)))
10099 if (sRef_isDependent (rs))
10101 sRef_setDependent (os, loc);
10105 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10110 branchStateError (res, other, flip, cl, loc);
10115 if (sRef_isKept (rs))
10117 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10118 sRef_setKept (os, loc);
10123 if (uentry_incompatibleMemoryStates (os, rs))
10125 if (uentry_relevantReference (rs, !flip))
10127 if (sRef_isLocalParamVar (rs)
10128 && (sRef_isDependent (rs)
10129 || sRef_isLocalState (rs)))
10131 if (sRef_isDependent (os))
10133 sRef_setDependent (rs, loc);
10137 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10142 if (sRef_isParam (os))
10145 ** If the local variable associated
10146 ** with the param has the correct state,
10148 ** (e.g., free (s); s = new(); ...
10151 uentry uvar = usymtab_lookupSafe (other->uname);
10153 if (uentry_isValid (uvar)
10154 && ((sRef_isDead (os)
10155 && sRef_isOnly (uvar->sref))
10156 || (sRef_isDependent (os)
10157 && sRef_isOwned (uvar->sref))))
10163 branchStateAltError (res, other,
10169 DPRINTF (("Here: %s / %s",
10170 uentry_unparseFull (res),
10171 uentry_unparseFull (other)));
10173 branchStateAltError (res, other,
10180 if (sRef_isKept (os))
10182 sRef_setKept (rs, loc);
10188 DPRINTF (("Merge opt..."));
10189 sRef_mergeOptState (rs, os, cl, loc);
10190 DPRINTF (("Done!"));
10194 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10195 sRef_mergeState (rs, os, cl, loc);
10196 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10201 if (sRef_isModified (os))
10203 sRef_setModified (rs);
10208 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10212 uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10214 valueTable rvalues;
10215 valueTable ovalues;
10217 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10225 rvalues = sRef_getValueTable (res->sref);
10226 ovalues = sRef_getValueTable (other->sref);
10228 if (valueTable_isUndefined (ovalues))
10230 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10233 else if (valueTable_isUndefined (rvalues))
10236 ** Copy values from other
10240 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10241 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10246 valueTable_elements (ovalues, fkey, fval) {
10248 metaStateInfo minfo;
10249 stateCombinationTable sctable;
10253 tval = valueTable_lookup (rvalues, fkey);
10255 DPRINTF (("Merge value: %s / %s X %s", fkey,
10256 stateValue_unparse (fval), stateValue_unparse (tval)));
10258 minfo = context_lookupMetaStateInfo (fkey);
10259 llassert (stateValue_isDefined (tval));
10261 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10263 DPRINTF (("Cannot find meta state for: %s", fkey));
10268 llassert (metaStateInfo_isDefined (minfo));
10270 if (stateValue_isError (fval)
10271 || sRef_definitelyNullContext (res->sref))
10273 sRef_setMetaStateValueComplete (res->sref,
10274 fkey, stateValue_getValue (fval),
10275 stateValue_getLoc (fval));
10276 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10278 else if (stateValue_isError (tval)
10279 || sRef_definitelyNullAltContext (other->sref))
10281 DPRINTF (("Other branch is definitely null!"));
10283 else if (sRef_isStateUndefined (res->sref)
10284 || sRef_isDead (res->sref))
10286 ; /* Combination state doesn't matter if it is undefined or dead */
10290 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10291 metaStateInfo_unparse (minfo),
10292 stateValue_unparse (fval),
10293 stateValue_unparse (tval)));
10295 DPRINTF (("state values: %d / %d",
10296 stateValue_getValue (fval), stateValue_getValue (tval)));
10298 sctable = metaStateInfo_getMergeTable (minfo);
10300 DPRINTF (("Merge table: %s",
10301 stateCombinationTable_unparse (sctable)));
10303 msg = cstring_undefined;
10305 nval = stateCombinationTable_lookup (sctable,
10306 stateValue_getValue (fval),
10307 stateValue_getValue (tval),
10310 DPRINTF (("nval: %d / %d / %d", nval,
10311 stateValue_getValue (fval), stateValue_getValue (tval)));
10313 if (nval == stateValue_error)
10315 /*@i32 print extra info for assignments@*/
10317 if (uentry_isGlobalMarker (res))
10322 ("Control branches merge with incompatible global states (%s and %s)%q",
10323 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10324 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10325 cstring_isDefined (msg)
10326 ? message (": %s", msg) : cstring_undefined),
10329 sRef_showMetaStateInfo (res->sref, fkey);
10330 sRef_showMetaStateInfo (other->sref, fkey);
10338 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10339 uentry_getName (res),
10340 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10341 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10342 cstring_isDefined (msg)
10343 ? message (": %s", msg) : cstring_undefined),
10346 sRef_showMetaStateInfo (res->sref, fkey);
10347 sRef_showMetaStateInfo (other->sref, fkey);
10348 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10349 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10350 DPRINTF (("Null: %s / %s",
10351 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10352 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10358 if (nval == stateValue_getValue (fval)
10359 && nval != stateValue_getValue (tval))
10361 loc = stateValue_getLoc (fval);
10363 else if (nval == stateValue_getValue (tval)
10364 && nval != stateValue_getValue (fval))
10366 loc = stateValue_getLoc (tval);
10373 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10374 && nval == stateValue_getValue (fval)
10375 && nval == stateValue_getValue (tval))
10381 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10385 } end_valueTable_elements ;
10391 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10392 bool flip, clause cl)
10394 if (cl == DOWHILECLAUSE)
10396 res->used = other->used || res->used;
10397 res->lset = other->lset || res->lset;
10398 res->uses = filelocList_append (res->uses, other->uses);
10399 other->uses = filelocList_undefined;
10403 if (sRef_isMacroParamRef (res->sref)
10404 && !uentry_isSefParam (other)
10405 && !uentry_isSefParam (res))
10407 bool hasError = FALSE;
10409 if (bool_equal (res->used, other->used))
10411 res->used = other->used;
10415 if (other->used && !flip)
10420 message ("Macro parameter %q used in true clause, "
10421 "but not in false clause",
10422 uentry_getName (res)),
10423 uentry_whereDeclared (res));
10430 message ("Macro parameter %q used in false clause, "
10431 "but not in true clause",
10432 uentry_getName (res)),
10433 uentry_whereDeclared (res));
10439 /* make it sef now, prevent more errors */
10440 res->info->var->kind = VKREFSEFPARAM;
10446 res->used = other->used || res->used;
10447 res->lset = other->lset || res->lset;
10448 res->uses = filelocList_append (res->uses, other->uses);
10449 other->uses = filelocList_undefined;
10455 uentry_mergeState (uentry res, uentry other, fileloc loc,
10456 bool mustReturn, bool flip, bool opt,
10459 llassert (uentry_isValid (res));
10460 llassert (uentry_isValid (other));
10462 llassert (res->ukind == other->ukind);
10463 llassert (res->ukind == KVAR);
10465 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10466 uentry_unparseFull (other)));
10468 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10469 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10470 uentry_mergeSetStates (res, other, loc, flip, cl);
10473 void uentry_setUsed (uentry e, fileloc loc)
10475 static bool firstTime = TRUE;
10476 static bool showUses = FALSE;
10477 static bool exportLocal = FALSE;
10479 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10483 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10485 showUses = context_getFlag (FLG_SHOWUSES);
10486 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10491 if (uentry_isValid (e))
10495 if (warnClause_isDefined (e->warn))
10497 flagSpec flg = warnClause_getFlag (e->warn);
10500 if (warnClause_hasMessage (e->warn))
10502 msg = cstring_copy (warnClause_getMessage (e->warn));
10506 msg = message ("Use of possibly dangerous %s",
10507 uentry_ekindNameLC (e));
10511 message ("%q: %q", msg, uentry_getName (e)),
10515 if (sRef_isMacroParamRef (e->sref))
10517 if (uentry_isYield (e) || uentry_isSefParam (e))
10523 if (context_inConditional ())
10527 message ("Macro parameter %q used in conditionally "
10528 "executed code (may or may not be "
10529 "evaluated exactly once)",
10530 uentry_getName (e)),
10533 e->info->var->kind = VKREFSEFPARAM;
10542 message ("Macro parameter %q used more than once",
10543 uentry_getName (e)),
10544 uentry_whereDeclared (e)))
10546 e->info->var->kind = VKREFSEFPARAM;
10553 if ((dp = uentry_directParamNo (e)) >= 0)
10555 uentry_setUsed (usymtab_getParam (dp), loc);
10560 if (!sRef_isLocalVar (e->sref))
10564 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10570 if (context_inMacro ())
10572 e->uses = filelocList_addUndefined (e->uses);
10576 e->uses = filelocList_addDifferentFile
10578 uentry_whereDeclared (e),
10587 bool uentry_isReturned (uentry u)
10589 return (uentry_isValid (u) && uentry_isVar (u)
10590 && (u->info->var->kind == VKRETPARAM
10591 || u->info->var->kind == VKSEFRETPARAM));
10594 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10596 llassert (uentry_isRealFunction (u));
10598 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10600 stateClauseList clauses = uentry_getStateClauseList (u);
10601 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10603 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10604 sRef_setAllocated (res, g_currentloc);
10606 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10607 stateClauseList_unparse (clauses)));
10610 ** This should be in exprNode_reflectEnsuresClause
10613 stateClauseList_postElements (clauses, cl)
10615 if (!stateClause_isGlobal (cl))
10617 sRefSet refs = stateClause_getRefs (cl);
10618 sRefMod modf = stateClause_getEffectFunction (cl);
10620 sRefSet_elements (refs, el)
10622 sRef base = sRef_getRootBase (el);
10624 if (sRef_isResult (base))
10628 sRef sr = sRef_fixBase (el, res);
10629 modf (sr, g_currentloc);
10636 } end_sRefSet_elements ;
10638 } end_stateClauseList_postElements ;
10646 sRefSet prefs = sRefSet_new ();
10647 sRef res = sRef_undefined;
10650 params = uentry_getParams (u);
10652 uentryList_elements (params, current)
10654 if (uentry_isReturned (current))
10656 if (exprNodeList_size (args) >= paramno)
10658 exprNode ecur = exprNodeList_nth (args, paramno);
10659 sRef tref = exprNode_getSref (ecur);
10661 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10663 if (sRef_isValid (tref))
10665 sRef tcref = sRef_copy (tref);
10667 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10669 if (sRef_isDead (tcref))
10671 sRef_setDefined (tcref, g_currentloc);
10672 sRef_setOnly (tcref, g_currentloc);
10675 if (sRef_isRefCounted (tcref))
10677 /* could be a new ref now (but only if its returned) */
10678 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10681 sRef_makeSafe (tcref);
10682 prefs = sRefSet_insert (prefs, tcref);
10688 } end_uentryList_elements ;
10690 if (sRefSet_size (prefs) > 0)
10692 nstate n = sRef_getNullState (u->sref);
10694 if (sRefSet_size (prefs) == 1)
10696 res = sRefSet_choose (prefs);
10700 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10701 res = sRefSet_mergeIntoOne (prefs);
10704 if (nstate_isKnown (n))
10706 sRef_setNullState (res, n, g_currentloc);
10711 if (ctype_isFunction (u->utype))
10713 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10714 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10718 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10721 if (sRef_isRefCounted (res))
10723 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10728 if (sRef_getNullState (res) == NS_ABSNULL)
10730 ctype ct = ctype_realType (u->utype);
10732 if (ctype_isAbstract (ct))
10734 sRef_setNotNull (res, g_currentloc);
10738 if (ctype_isUser (ct))
10740 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10744 sRef_setNotNull (res, g_currentloc);
10749 if (sRef_isRefCounted (res))
10751 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10753 else if (sRef_isKillRef (res))
10755 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10762 ak = sRef_getAliasKind (res);
10764 if (alkind_isImplicit (ak))
10766 sRef_setAliasKind (res,
10767 alkind_fixImplicit (ak),
10771 sRefSet_free (prefs);
10773 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10778 static bool uentry_isRefCounted (uentry ue)
10780 ctype ct = uentry_getType (ue);
10782 if (ctype_isFunction (ct))
10784 return (ctype_isRefCounted (ctype_getReturnType (ct)));
10788 return (ctype_isRefCounted (ct));
10793 ** old was declared yield in the specification.
10794 ** new is declared in the iter implementation.
10797 void uentry_checkYieldParam (uentry old, uentry unew)
10801 llassert (uentry_isVariable (old));
10802 llassert (uentry_isVariable (unew));
10804 unew->info->var->kind = VKYIELDPARAM;
10805 (void) checkTypeConformance (old, unew, TRUE);
10806 checkVarConformance (old, unew, TRUE, FALSE);
10808 /* get rid of param marker */
10810 name = uentry_getName (unew);
10811 cstring_free (unew->uname);
10812 unew->uname = name;
10813 unew->info->var->kind = VKREFYIELDPARAM;
10815 uentry_setUsed (old, fileloc_undefined);
10816 uentry_setUsed (unew, fileloc_undefined);
10819 /*@observer@*/ cstring
10820 uentry_ekindName (uentry ue)
10822 if (uentry_isValid (ue))
10827 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10829 return cstring_makeLiteralTemp ("Datatype");
10831 return cstring_makeLiteralTemp ("Enum member");
10833 return cstring_makeLiteralTemp ("Constant");
10835 if (uentry_isParam (ue))
10837 return cstring_makeLiteralTemp ("Parameter");
10839 else if (uentry_isExpandedMacro (ue))
10841 return cstring_makeLiteralTemp ("Expanded macro");
10845 return cstring_makeLiteralTemp ("Variable");
10848 return cstring_makeLiteralTemp ("Function");
10850 return cstring_makeLiteralTemp ("Iterator");
10852 return cstring_makeLiteralTemp ("Iterator finalizer");
10854 return cstring_makeLiteralTemp ("Struct tag");
10856 return cstring_makeLiteralTemp ("Union tag");
10858 return cstring_makeLiteralTemp ("Enum tag");
10860 return cstring_makeLiteralTemp ("Optional parameters");
10865 return cstring_makeLiteralTemp ("<Undefined>");
10871 /*@observer@*/ cstring
10872 uentry_ekindNameLC (uentry ue)
10874 if (uentry_isValid (ue))
10879 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10881 return cstring_makeLiteralTemp ("datatype");
10883 return cstring_makeLiteralTemp ("enum member");
10885 return cstring_makeLiteralTemp ("constant");
10887 if (uentry_isParam (ue))
10889 return cstring_makeLiteralTemp ("parameter");
10891 else if (uentry_isExpandedMacro (ue))
10893 return cstring_makeLiteralTemp ("expanded macro");
10897 return cstring_makeLiteralTemp ("variable");
10900 return cstring_makeLiteralTemp ("function");
10902 return cstring_makeLiteralTemp ("iterator");
10904 return cstring_makeLiteralTemp ("iterator finalizer");
10906 return cstring_makeLiteralTemp ("struct tag");
10908 return cstring_makeLiteralTemp ("union tag");
10910 return cstring_makeLiteralTemp ("enum tag");
10912 return cstring_makeLiteralTemp ("optional parameters");
10917 return cstring_makeLiteralTemp ("<Undefined>");
10923 void uentry_setHasNameError (uentry ue)
10925 llassert (uentry_isValid (ue));
10927 ue->hasNameError = TRUE;
10930 void uentry_checkName (uentry ue)
10932 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10933 uentry_observeRealName (ue),
10934 bool_unparse (uentry_isVisibleExternally (ue))));
10936 if (uentry_isValid (ue)
10937 && !context_inXHFile ()
10938 && uentry_hasName (ue)
10939 && !uentry_isElipsisMarker (ue)
10940 && context_getFlag (FLG_NAMECHECKS)
10941 && !ue->hasNameError
10942 && !uentry_isEndIter (ue)
10943 && !fileloc_isBuiltin (uentry_whereLast (ue))
10944 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10946 DPRINTF (("Here..."));
10948 if (uentry_isPriv (ue))
10950 ; /* any checks here? */
10952 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10954 ; /* no errors for externals */
10960 if (uentry_isExpandedMacro (ue))
10966 if (uentry_isExpandedMacro (ue))
10970 else if (uentry_isVariable (ue))
10972 sRef sr = uentry_getSref (ue);
10974 if (sRef_isValid (sr))
10976 scope = sRef_getScope (sr);
10983 else if (uentry_isFunction (ue)
10984 || uentry_isIter (ue)
10985 || uentry_isEndIter (ue)
10986 || uentry_isConstant (ue))
10988 scope = uentry_isStatic (ue) ? fileScope : globScope;
10990 else /* datatypes, etc. must be global */
10995 usymtab_checkDistinctName (ue, scope);
10998 if (context_getFlag (FLG_CPPNAMES))
11003 if (scope == globScope)
11005 checkExternalName (ue);
11007 else if (scope == fileScope)
11009 checkFileScopeName (ue);
11013 checkLocalName (ue);
11017 checkAnsiName (ue);
11022 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11028 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11031 if (!context_inMacro ())
11033 sRef_setGlobalScopeSafe ();
11036 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11037 uentry_setUsed (ue, loc);
11039 tloc = fileloc_createExternal ();
11040 uentry_setDefined (ue, tloc);
11041 fileloc_free (tloc);
11042 uentry_setHasNameError (ue);
11044 if (context_getFlag (FLG_REPEATUNRECOG))
11046 uentry_markOwned (ue);
11050 ue = usymtab_supReturnFileEntry (ue);
11053 if (!context_inMacro ())
11055 sRef_clearGlobalScopeSafe ();
11061 uentry uentry_makeGlobalMarker ()
11066 llassert (sRef_inGlobalScope ());
11068 ue = uentry_makeVariableAux
11069 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11070 sRef_makeGlobalMarker (),
11073 tloc = fileloc_createExternal ();
11074 uentry_setUsed (ue, tloc);
11075 uentry_setDefined (ue, tloc);
11076 fileloc_free (tloc);
11077 uentry_setHasNameError (ue);
11083 bool uentry_isGlobalMarker (uentry ue)
11085 return (uentry_isValid (ue)
11086 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11089 /* new start modifications */
11091 /* start modifications */
11093 requires: p_e is defined, is a ptr/array variable
11095 effects: sets the state of the variable
11099 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
11100 /*@access sRef@*/ /*i523 shouldn't do this! */
11101 if( uentry_isValid(p_e) ) {
11102 if( p_e->info != NULL) {
11103 if( p_e->info->var != NULL) {
11104 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11105 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11110 /*@noaccess sRef@*/
11112 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11116 requires: p_e is defined, is a ptr/array variable
11118 effects: sets the size of the buffer
11121 void uentry_setNullTerminatedState (uentry p_e) {
11122 if( uentry_isValid(p_e) ) {
11123 if( p_e->info != NULL) {
11124 if( p_e->info->var != NULL) {
11125 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11126 /*@access sRef@*/ /*@i523 bad!*/
11127 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11128 /*@noaccess sRef@*/
11134 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11138 requires: p_e is defined, is a ptr/array variable
11140 effects: sets the size of the buffer
11143 void uentry_setSize (uentry p_e, int size) {
11144 if( uentry_isValid(p_e) ) {
11145 if( p_e->info != NULL) {
11146 if( p_e->info->var != NULL) {
11147 p_e->info->var->bufinfo->size = size;
11148 /*@access sRef@*/ /*@i523 bad!*/
11149 p_e->sref->bufinfo.size = size;
11150 /*@noaccess sRef@*/
11156 fprintf(stderr, "uentry:Error in setSize\n");
11161 requires: p_e is defined, is a ptr/array variable
11163 effects: sets the length of the buffer
11166 void uentry_setLen (uentry p_e, int len) {
11167 if( uentry_isValid(p_e) ) {
11168 if( p_e->info != NULL) {
11169 if( p_e->info->var != NULL) {
11170 p_e->info->var->bufinfo->len = len;
11171 /*@access sRef@*/ /*@i523 bad!*/
11172 p_e->sref->bufinfo.len = len;
11173 /*@noaccess sRef@*/
11179 fprintf(stderr, "uentry:Error in setLen\n");
11184 bool uentry_hasMetaStateEnsures (uentry e)
11186 if (uentry_isValid (e) && uentry_isFunction (e))
11188 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11196 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11198 llassert (uentry_isValid (e) && uentry_isFunction (e));
11199 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);