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) /*@modifies g_msgstream@*/ ;
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 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3364 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3367 ** expanded macro is marked used
3370 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3373 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3374 ue->info->fcn->exitCode = XK_UNKNOWN;
3375 ue->info->fcn->nullPred = qual_createUnknown ();
3376 ue->info->fcn->specialCode = SPC_NONE;
3377 ue->info->fcn->access = typeIdSet_undefined;
3378 ue->info->fcn->hasGlobs = FALSE;
3379 ue->info->fcn->globs = globSet_undefined;
3380 ue->info->fcn->hasMods = FALSE;
3381 ue->info->fcn->mods = sRefSet_undefined;
3382 ue->info->fcn->specclauses = NULL;
3383 ue->info->fcn->defparams = uentryList_undefined;
3386 ue->info->fcn->preconditions = functionConstraint_undefined;
3390 ue->info->fcn->postconditions = functionConstraint_undefined;
3393 if (ctype_isFunction (ue->utype))
3395 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3399 ue->sref = sRef_makeType (ctype_unknown);
3402 if (sRef_isRefCounted (ue->sref))
3408 if (alkind_isUnknown (ak))
3410 if (exkind_isKnown (ek))
3412 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3413 ak = AK_IMPDEPENDENT;
3417 if (context_getFlag (FLG_RETIMPONLY))
3419 if (ctype_isFunction (ue->utype)
3420 && ctype_isVisiblySharable
3421 (ctype_realType (ctype_getReturnType (ue->utype))))
3423 if (uentryList_hasReturned (uentry_getParams (ue)))
3429 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3444 loc = ue->whereDeclared;
3446 sRef_setAliasKind (ue->sref, ak, loc);
3447 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3448 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3449 sRef_setExKind (ue->sref, ek, loc);
3451 if (oldInfo->kind == VKEXPMACRO)
3457 fileloc_free (ue->whereDefined);
3458 ue->whereDefined = fileloc_undefined;
3461 uvinfo_free (oldInfo);
3464 void uentry_makeConstantFunction (uentry ue)
3471 llassert (uentry_isValid (ue));
3472 llassert (!sRef_modInFunction ());
3474 ak = sRef_getOrigAliasKind (ue->sref);
3475 ek = sRef_getOrigExKind (ue->sref);
3477 llassert (uentry_isConstant (ue));
3478 oldInfo = ue->info->uconst;
3480 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3483 ** expanded macro is marked used (until I write a pre-processor)
3487 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3488 ue->info->fcn->exitCode = XK_UNKNOWN;
3489 ue->info->fcn->nullPred = qual_createUnknown ();
3490 ue->info->fcn->specialCode = SPC_NONE;
3491 ue->info->fcn->access = typeIdSet_undefined;
3492 ue->info->fcn->hasGlobs = FALSE;
3493 ue->info->fcn->globs = globSet_undefined;
3494 ue->info->fcn->hasMods = FALSE;
3495 ue->info->fcn->mods = sRefSet_undefined;
3496 ue->info->fcn->specclauses = NULL;
3497 ue->info->fcn->defparams = uentryList_undefined;
3500 ue->info->fcn->preconditions = functionConstraint_undefined;
3504 ue->info->fcn->postconditions = functionConstraint_undefined;
3508 if (ctype_isFunction (ue->utype))
3510 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3514 ue->sref = sRef_makeType (ctype_unknown);
3517 if (sRef_isRefCounted (ue->sref))
3523 if (alkind_isUnknown (ak))
3525 if (exkind_isKnown (ek))
3527 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3528 ak = AK_IMPDEPENDENT;
3532 if (context_getFlag (FLG_RETIMPONLY))
3534 if (ctype_isFunction (ue->utype)
3535 && ctype_isVisiblySharable
3536 (ctype_realType (ctype_getReturnType (ue->utype))))
3538 if (uentryList_hasReturned (uentry_getParams (ue)))
3544 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3559 loc = ue->whereDeclared;
3561 sRef_setAliasKind (ue->sref, ak, loc);
3562 sRef_setExKind (ue->sref, ek, loc);
3564 fileloc_free (ue->whereDefined);
3565 ue->whereDefined = fileloc_undefined;
3566 ucinfo_free (oldInfo);
3570 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3572 llassert (uentry_isValid (ue));
3574 if (uentry_isIter (ue))
3576 llassert (globSet_isUndefined (ue->info->iter->globs));
3577 ue->info->iter->globs = globs;
3581 uentry_convertVarFunction (ue);
3583 llassert (uentry_isFunction (ue));
3584 llassert (!ue->info->fcn->hasGlobs
3585 && globSet_isUndefined (ue->info->fcn->globs));
3587 ue->info->fcn->hasGlobs = TRUE;
3588 globSet_markImmutable (globs);
3589 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3594 /* ??? - evans 2001-09-09 not sure what's going on here...?
3595 if (globSet_hasStatic (globs))
3597 context_recordFileGlobals (globs);
3601 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3603 ue->info->fcn->hasMods = TRUE;
3607 void uentry_addAccessType (uentry ue, typeId tid)
3609 if (uentry_isFunction (ue))
3611 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3613 else if (uentry_isEitherConstant (ue))
3615 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3617 else if (uentry_isIter (ue))
3619 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3621 else if (uentry_isEndIter (ue))
3623 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3627 llbug (message ("no access for: %q", uentry_unparse (ue)));
3631 /*@only@*/ /*@notnull@*/ uentry
3632 uentry_makeFunction (cstring n, ctype t,
3634 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3635 /*@only@*/ warnClause warn,
3638 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3639 return (uentry_makeFunctionAux (n, t,
3640 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3641 : typeIdSet_single (access)),
3648 /*@notnull@*/ uentry
3649 uentry_makePrivFunction2 (cstring n, ctype t,
3651 globSet globs, sRefSet mods,
3654 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3659 /*@notnull@*/ uentry
3660 uentry_makeSpecFunction (cstring n, ctype t,
3662 /*@only@*/ globSet globs,
3663 /*@only@*/ sRefSet mods,
3666 uentry ue = uentry_makeFunctionAux (n, t, access,
3667 globs, mods, warnClause_undefined,
3670 uentry_setHasGlobs (ue);
3671 uentry_setHasMods (ue);
3673 reflectImplicitFunctionQualifiers (ue, TRUE);
3678 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3680 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3681 sRef_undefined, FALSE, VKEXPMACRO);
3683 uentry_setDefined (ue, f);
3687 /*@notnull@*/ /*@notnull@*/ uentry
3688 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3690 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3691 typeIdSet_singleOpt (access),
3692 globSet_undefined, sRefSet_undefined,
3693 warnClause_undefined,
3697 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3701 bool uentry_isForward (uentry e)
3703 if (uentry_isValid (e))
3705 ctype ct = uentry_getType (e);
3707 return (ctype_isUnknown (ct)
3708 || (ctype_isFunction (ct)
3709 && ctype_isUnknown (ctype_getReturnType (ct))));
3716 /*@notnull@*/ uentry
3717 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3719 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3720 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3724 /*@notnull@*/ uentry
3725 uentry_makeUnspecFunction (cstring n, ctype t,
3729 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3730 sRefSet_undefined, warnClause_undefined,
3733 reflectImplicitFunctionQualifiers (ue, TRUE);
3742 /* is exported for use by usymtab_interface */
3744 /*@notnull@*/ uentry
3745 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3746 fileloc f, bool priv)
3748 uentry e = uentry_alloc ();
3750 DPRINTF (("Make datatype: %s / %s",
3751 n, ctype_unparse (t)));
3753 /* e->shallowCopy = FALSE; */
3754 e->ukind = KDATATYPE;
3755 e->uname = cstring_copy (n);
3757 e->storageclass = SCNONE;
3758 e->sref = sRef_makeUnknown ();
3762 sRef_setStateFromType (e->sref, t);
3765 uentry_setSpecDef (e, f);
3767 e->warn = warnClause_undefined; /*@i634@*/
3768 e->uses = filelocList_new ();
3769 e->isPrivate = priv;
3770 e->hasNameError = FALSE;
3775 e->info = (uinfo) dmalloc (sizeof (*e->info));
3776 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3777 e->info->datatype->abs = abstract;
3778 e->info->datatype->mut = mut;
3779 e->info->datatype->type = ctype_undefined;
3781 if (uentry_isDeclared (e))
3783 uentry_setDefined (e, f);
3786 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3788 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3794 /*@notnull@*/ uentry
3795 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3797 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3800 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3802 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3803 ctype_bool, NO, abstract,
3804 fileloc_getBuiltin (),
3807 ret->info->datatype->type = ctype_bool;
3815 static /*@only@*/ /*@notnull@*/ uentry
3816 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3817 /*@only@*/ fileloc f)
3819 uentry e = uentry_alloc ();
3822 e->uname = cstring_copy (n);
3824 e->sref = sRef_makeUnknown ();
3825 e->storageclass = SCNONE;
3829 uentry_setSpecDef (e, f);
3831 e->warn = warnClause_undefined; /*@i452@*/
3832 e->uses = filelocList_new ();
3833 e->isPrivate = FALSE;
3834 e->hasNameError = FALSE;
3836 e->info = (uinfo) dmalloc (sizeof (*e->info));
3837 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3838 e->info->iter->access = access;
3839 e->info->iter->mods = sRefSet_undefined;
3840 e->info->iter->globs = globSet_undefined;
3842 uentry_checkIterArgs (e);
3846 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3848 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3851 static /*@notnull@*/ uentry
3852 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3854 uentry e = uentry_alloc ();
3856 /* e->shallowCopy = FALSE; */
3857 e->ukind = KENDITER;
3858 e->storageclass = SCNONE;
3859 e->uname = message ("end_%s", n);
3860 e->utype = ctype_unknown;
3861 e->sref = sRef_makeUnknown ();
3863 uentry_setSpecDef (e, f);
3868 e->uses = filelocList_new ();
3869 e->isPrivate = FALSE;
3870 e->hasNameError = FALSE;
3872 e->info = (uinfo) dmalloc (sizeof (*e->info));
3873 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3875 e->info->enditer->access = access;
3877 e->warn = warnClause_undefined; /*@i452@*/
3881 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3883 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3890 static /*@only@*/ /*@notnull@*/ uentry
3891 uentry_makeTagAux (cstring n, ctype t,
3892 /*@only@*/ fileloc fl,
3893 bool priv, ekind kind)
3895 uentry e = uentry_alloc ();
3897 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3899 llbuglit ("uentry_makeTagAux: not a tag type");
3903 /* e->shallowCopy = FALSE; */
3904 e->uname = cstring_copy (n);
3907 e->sref = sRef_makeUnknown ();
3908 e->storageclass = SCNONE;
3910 uentry_setSpecDef (e, fl);
3915 e->uses = filelocList_new ();
3916 e->isPrivate = priv;
3917 e->hasNameError = FALSE;
3919 e->info = (uinfo) dmalloc (sizeof (*e->info));
3920 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3921 e->info->datatype->abs = NO;
3922 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3923 e->info->datatype->type = t;
3924 e->warn = warnClause_undefined; /*@i452@*/
3926 if (uentry_isDeclared (e))
3928 uentry_setDefined (e, fl);
3934 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3936 cstring sname = makeStruct (n);
3937 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3939 cstring_free (sname);
3944 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3946 cstring sname = makeStruct (n);
3947 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3949 cstring_free (sname);
3954 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3956 cstring uname = makeUnion (n);
3957 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3959 cstring_free (uname);
3965 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3967 cstring ename = makeEnum (n);
3968 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3970 cstring_free (ename);
3976 uentry_makeUnionTagLoc (cstring n, ctype t)
3978 cstring uname = makeUnion (n);
3979 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3981 cstring_free (uname);
3986 uentry_makeEnumTagLoc (cstring n, ctype t)
3988 cstring ename = makeEnum (n);
3989 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3991 cstring_free (ename);
3996 uentry_isStructTag (uentry ue)
3998 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4002 uentry_isUnionTag (uentry ue)
4004 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4008 uentry_isEnumTag (uentry ue)
4010 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4014 uentry_isAnyTag (uentry ue)
4016 return (uentry_isStructTag (ue)
4017 || uentry_isUnionTag (ue)
4018 || uentry_isEnumTag (ue));
4021 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4023 extern void uentry_destroyMod (void)
4024 /*@globals killed emarker@*/ /*@modifies emarker@*/
4026 static bool wasDestroyed = FALSE;
4028 llassert (!wasDestroyed);
4030 if (emarker != NULL)
4032 uentry_reallyFree (emarker);
4035 wasDestroyed = TRUE;
4039 uentry_makeElipsisMarker (void)
4041 if (emarker == NULL)
4043 emarker = uentry_alloc ();
4045 emarker->ukind = KELIPSMARKER;
4046 emarker->uname = cstring_makeLiteral ("...");
4047 emarker->utype = ctype_elipsMarker;
4048 emarker->sref = sRef_undefined;
4049 emarker->storageclass = SCNONE;
4050 emarker->used = FALSE;
4051 emarker->lset = FALSE;
4052 emarker->info = NULL;
4054 uentry_setSpecDef (emarker, fileloc_undefined);
4055 emarker->uses = filelocList_new ();
4056 emarker->isPrivate = FALSE;
4057 emarker->hasNameError = FALSE;
4060 /*@ignore@*/ return (emarker); /*@end@*/
4068 uentry_equiv (uentry p1, uentry p2)
4070 if (uentry_compare (p1, p2) != 0)
4081 uentry_xcomparealpha (uentry *p1, uentry *p2)
4085 if ((res = uentry_compare (*p1, *p2)) == 0) {
4086 if ((*p1 != NULL) && (*p2 != NULL)) {
4087 res = cstring_compare ((*p1)->uname,
4096 uentry_xcompareuses (uentry *p1, uentry *p2)
4101 if (uentry_isValid (u1))
4103 if (uentry_isValid (u2))
4105 return (-1 * int_compare (filelocList_size (u1->uses),
4106 filelocList_size (u2->uses)));
4115 if (uentry_isValid (u2))
4127 uentry_compareStrict (uentry v1, uentry v2)
4129 COMPARERETURN (uentry_compare (v1, v2));
4131 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4133 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4134 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4135 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4142 uentry_compare (uentry u1, uentry u2)
4144 if (u1 == u2) return 0;
4146 if (uentry_isInvalid (u1)) return -1;
4147 if (uentry_isInvalid (u2)) return 1;
4149 INTCOMPARERETURN (u1->ukind, u2->ukind);
4150 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4151 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4152 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4158 /* bug detected by lclint:
4159 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4164 return (multiVal_compare (uentry_getConstantValue (u1),
4165 uentry_getConstantValue (u2)));
4169 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4171 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4172 uentry_accessType (u2)));
4173 return (uentryList_compareParams (uentry_getParams (u1),
4174 uentry_getParams (u2)));
4176 return (typeIdSet_compare (uentry_accessType (u1),
4177 uentry_accessType (u2)));
4180 ** Functions are never equivalent
4183 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4193 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4194 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4195 sRef_getOrigAliasKind (u2->sref)));
4196 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4197 sRef_getOrigExKind (u2->sref)));
4198 COMPARERETURN (generic_compare (u1->info->var->checked,
4199 u2->info->var->checked));
4200 COMPARERETURN (generic_compare (u1->info->var->defstate,
4201 u2->info->var->defstate));
4202 return (generic_compare (u1->info->var->nullstate,
4203 u2->info->var->nullstate));
4205 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4206 u2->info->datatype->type));
4207 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4208 u2->info->datatype->mut));
4209 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4218 ** all entries are: <type>[@<info>]*#<name>
4220 ** info depends on kind:
4224 advanceField (char **s)
4226 reader_checkChar (s, '@');
4230 advanceName (char **s)
4232 reader_checkChar (s, '#');
4236 vkind_fromInt (int i)
4238 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4240 llbuglit ("vkind_fromInt: out of range");
4247 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4248 typeIdSet access, nstate nullstate,
4249 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4251 uentry e = uentry_alloc ();
4256 e->sref = sRef_makeConst (ct);
4258 sRef_setNullState (e->sref, nullstate, loc);
4259 e->storageclass = SCNONE;
4261 if (fileloc_isSpec (loc))
4263 e->whereSpecified = loc;
4264 e->whereDeclared = fileloc_undefined;
4268 e->whereSpecified = fileloc_undefined;
4269 e->whereDeclared = loc;
4272 e->whereDefined = fileloc_undefined;
4273 e->uses = filelocList_new ();
4274 e->isPrivate = FALSE;
4275 e->hasNameError = FALSE;
4280 e->warn = warnClause_undefined; /*@i452@*/
4282 e->info = (uinfo) dmalloc (sizeof (*e->info));
4283 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4284 e->info->uconst->access = access;
4286 uentry_setConstantValue (e, m);
4287 sRef_storeState (e->sref);
4292 static /*@only@*/ uentry
4293 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4294 sstate defstate, nstate isnull, alkind aliased,
4295 exkind exp, chkind checked,
4296 /*@only@*/ fileloc loc)
4298 uentry e = uentry_alloc ();
4303 e->storageclass = SCNONE;
4305 e->sref = sRef_makeType (ct);
4306 sRef_setNullState (e->sref, isnull, loc);
4308 e->whereDefined = fileloc_undefined;
4310 if (fileloc_isSpec (loc))
4312 e->whereSpecified = loc;
4313 e->whereDeclared = fileloc_undefined;
4317 e->whereSpecified = fileloc_undefined;
4318 e->whereDeclared = loc;
4321 e->isPrivate = FALSE;
4322 e->hasNameError = FALSE;
4327 e->uses = filelocList_new ();
4328 e->warn = warnClause_undefined; /*@i452@*/
4330 e->info = (uinfo) dmalloc (sizeof (*e->info));
4331 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4332 e->info->var->kind = kind;
4333 e->info->var->checked = checked;
4334 e->info->var->defstate = defstate;
4336 sRef_setDefState (e->sref, defstate, loc);
4338 e->info->var->nullstate = sRef_getNullState (e->sref);
4340 sRef_setExKind (e->sref, exp, loc);
4341 sRef_setAliasKind (e->sref, aliased, loc);
4343 sRef_storeState (e->sref);
4345 /*DRL ADDED 9-1-2000 */
4346 e->info->var->bufinfo = NULL;
4351 static /*@only@*/ uentry
4352 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4353 ynm mut, ctype rtype, alkind ak, exkind exp,
4354 sstate defstate, nstate isnull,
4355 /*@only@*/ fileloc loc)
4357 uentry e = uentry_alloc ();
4359 e->ukind = KDATATYPE;
4360 /* e->shallowCopy = FALSE; */
4363 e->storageclass = SCNONE;
4364 e->sref = sRef_makeUnknown ();
4365 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4368 ** This is only setting null state. (I think?)
4371 if (ctype_isUA (ct))
4373 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4375 if (uentry_isValid (te))
4377 sRef_setStateFromUentry (e->sref, te);
4381 /* problem for recursive type definitions */
4385 sRef_setAliasKind (e->sref, ak, loc);
4386 sRef_setExKind (e->sref, exp, loc);
4388 sRef_setDefState (e->sref, defstate, loc);
4390 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4392 isnull = NS_ABSNULL;
4395 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4396 sRef_mergeNullState (e->sref, isnull);
4398 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4400 if (fileloc_isSpec (loc))
4402 e->whereSpecified = loc;
4403 e->whereDeclared = fileloc_undefined;
4407 e->whereSpecified = fileloc_undefined;
4408 e->whereDeclared = loc;
4411 e->isPrivate = FALSE;
4412 e->hasNameError = FALSE;
4414 e->warn = warnClause_undefined; /*@i452@*/
4418 e->uses = filelocList_new ();
4420 e->info = (uinfo) dmalloc (sizeof (*e->info));
4421 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4422 e->info->datatype->abs = abstract;
4423 e->info->datatype->mut = mut;
4424 e->info->datatype->type = rtype;
4426 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4427 sRef_storeState (e->sref);
4428 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4434 static void uentry_setHasGlobs (uentry ue)
4436 llassert (uentry_isFunction (ue));
4438 ue->info->fcn->hasGlobs = TRUE;
4441 static void uentry_setHasMods (uentry ue)
4443 llassert (uentry_isFunction (ue));
4445 ue->info->fcn->hasMods = TRUE;
4449 bool uentry_hasGlobs (uentry ue)
4451 if (uentry_isFunction (ue))
4453 return (ue->info->fcn->hasGlobs);
4459 bool uentry_hasStateClauseList (uentry ue)
4461 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4464 bool uentry_hasConditions (uentry ue)
4466 return (uentry_isFunction (ue)
4467 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4468 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4471 stateClauseList uentry_getStateClauseList (uentry ue)
4473 if (!uentry_isFunction (ue))
4475 llassert (uentry_isFunction (ue));
4476 return stateClauseList_undefined;
4479 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4480 return ue->info->fcn->specclauses;
4483 bool uentry_hasMods (uentry ue)
4485 if (uentry_isFunction (ue))
4487 return (ue->info->fcn->hasMods);
4494 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4496 bool hasGlobs, /*@only@*/ globSet globs,
4497 bool hasMods, /*@only@*/ sRefSet mods,
4498 alkind ak, exkind exp,
4499 sstate defstate, nstate isnull,
4503 /*@only@*/ stateClauseList specclauses,
4504 /*@only@*/ warnClause warnclause,
4505 /*@only@*/ fileloc loc)
4507 uentry e = uentry_alloc ();
4510 /* e->shallowCopy = FALSE; */
4514 e->storageclass = SCNONE;
4516 if (ctype_isFunction (ct))
4518 ret = ctype_getReturnType (ct);
4522 if (ctype_isKnown (ct))
4524 llbug (message ("not function: %s", ctype_unparse (ct)));
4527 ret = ctype_unknown;
4530 e->sref = sRef_makeType (ret);
4532 if (ctype_isUA (ret))
4534 sRef_setStateFromType (e->sref, ret);
4537 sRef_setDefined (e->sref, loc);
4538 sRef_setNullState (e->sref, isnull, loc);
4540 sRef_setAliasKind (e->sref, ak, loc);
4541 sRef_setExKind (e->sref, exp, loc);
4542 sRef_setDefState (e->sref, defstate, loc);
4544 e->whereSpecified = loc;
4545 e->whereDefined = fileloc_undefined;
4547 e->isPrivate = FALSE;
4548 e->hasNameError = FALSE;
4552 e->uses = filelocList_new ();
4553 e->warn = warnclause;
4555 e->info = (uinfo) dmalloc (sizeof (*e->info));
4556 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4558 e->info->fcn->exitCode = exitCode;
4559 e->info->fcn->specialCode = sCode;
4560 e->info->fcn->nullPred = nullPred;
4561 e->info->fcn->access = access;
4563 e->info->fcn->specclauses = specclauses;
4564 e->info->fcn->hasGlobs = hasGlobs;
4565 e->info->fcn->globs = globs;
4567 e->info->fcn->hasMods = hasMods;
4568 e->info->fcn->mods = mods;
4570 e->info->fcn->defparams = uentryList_undefined;
4571 e->whereDeclared = fileloc_undefined;
4573 sRef_storeState (e->sref);
4576 e->info->fcn->preconditions = NULL;
4580 e->info->fcn->postconditions = NULL;
4586 static /*@only@*/ uentry
4587 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4588 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4590 uentry e = uentry_alloc ();
4592 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4594 llbuglit ("uentry_makeTagBase: not a tag type");
4597 /* e->shallowCopy = FALSE; */
4601 e->sref = sRef_makeUnknown ();
4602 e->storageclass = SCNONE;
4604 if (fileloc_isSpec (loc))
4606 e->whereSpecified = loc;
4607 e->whereDeclared = fileloc_undefined;
4611 e->whereDeclared = loc;
4612 e->whereSpecified = fileloc_undefined;
4615 e->whereDefined = fileloc_undefined;
4617 e->isPrivate = FALSE;
4618 e->hasNameError = FALSE;
4622 e->uses = filelocList_new ();
4623 e->warn = warnClause_undefined; /*@i452@*/
4625 e->info = (uinfo) dmalloc (sizeof (*e->info));
4626 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4627 e->info->datatype->abs = NO;
4628 e->info->datatype->mut = MAYBE;
4629 e->info->datatype->type = rtype;
4631 sRef_storeState (e->sref);
4637 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4638 ctype ct, /*@only@*/ fileloc loc)
4640 uentry e = uentry_alloc ();
4642 /* e->shallowCopy = FALSE; */
4646 e->sref = sRef_makeUnknown ();
4647 e->storageclass = SCNONE;
4649 if (fileloc_isSpec (loc))
4651 e->whereSpecified = loc;
4652 e->whereDeclared = fileloc_undefined;
4656 e->whereDeclared = loc;
4657 e->whereSpecified = fileloc_undefined;
4660 e->whereDefined = fileloc_undefined;
4662 e->isPrivate = FALSE;
4663 e->hasNameError = FALSE;
4667 e->uses = filelocList_new ();
4668 e->warn = warnClause_undefined; /*@i452@*/
4670 e->info = (uinfo) dmalloc (sizeof (*e->info));
4671 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4672 e->info->iter->access = access;
4673 e->info->iter->mods = sRefSet_undefined;
4674 e->info->iter->globs = globSet_undefined;
4676 sRef_storeState (e->sref);
4681 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4682 /*@only@*/ fileloc loc)
4684 uentry e = uentry_alloc ();
4686 /* e->shallowCopy = FALSE; */
4687 e->ukind = KENDITER;
4688 e->storageclass = SCNONE;
4690 e->utype = ctype_unknown;
4691 e->sref = sRef_makeUnknown ();
4693 if (fileloc_isSpec (loc))
4695 e->whereSpecified = loc;
4696 e->whereDeclared = fileloc_undefined;
4700 e->whereDeclared = loc;
4701 e->whereSpecified = fileloc_undefined;
4704 e->whereDefined = fileloc_undefined;
4706 e->isPrivate = FALSE;
4707 e->hasNameError = FALSE;
4711 e->uses = filelocList_new ();
4712 e->warn = warnClause_undefined; /*@i452@*/
4714 e->info = (uinfo) dmalloc (sizeof (*e->info));
4715 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4716 e->info->enditer->access = access;
4717 sRef_storeState (e->sref);
4722 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4730 uentry_undump (ekind kind, fileloc loc, char **s)
4734 DPRINTF (("Uentry undump: %s", *s));
4738 reader_checkChar (s, '!');
4739 reader_checkChar (s, '.');
4740 ue = uentry_makeElipsisMarker ();
4744 ctype ct = ctype_undump (s);
4758 reader_checkChar (s, '|');
4760 if (reader_optCheckChar (s, '@'))
4762 tkind = vkind_fromInt (reader_getInt (s));
4763 reader_checkChar (s, '|');
4770 if (reader_optCheckChar (s, '$'))
4772 defstate = SS_UNKNOWN;
4773 isnull = NS_UNKNOWN;
4774 aliased = AK_IMPTEMP;
4776 checked = CH_UNKNOWN;
4778 else if (reader_optCheckChar (s, '&'))
4780 defstate = SS_DEFINED;
4781 isnull = NS_UNKNOWN;
4782 aliased = AK_IMPTEMP;
4784 checked = CH_UNKNOWN;
4786 else if (reader_optCheckChar (s, '^'))
4788 defstate = SS_UNKNOWN;
4789 isnull = NS_UNKNOWN;
4790 aliased = AK_IMPTEMP;
4792 checked = CH_UNKNOWN;
4796 defstate = sstate_fromInt (reader_getInt (s));
4797 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4798 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4800 if (reader_optCheckChar (s, '&'))
4803 checked = CH_UNKNOWN;
4807 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4808 advanceField (s); checked = (chkind) (reader_getInt (s));
4813 name = reader_getStringWord (s);
4815 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4817 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4818 isnull, aliased, exp,
4819 checked, fileloc_copy (loc));
4832 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4833 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4834 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4835 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4836 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4837 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4838 advanceField (s); rtype = ctype_undump (s);
4840 name = reader_getStringWord (s);
4841 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4842 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4843 aliased, exp, defstate, isnull,
4844 fileloc_copy (loc));
4861 stateClauseList specclauses = stateClauseList_undefined;
4862 warnClause warnclause = warnClause_undefined;
4864 if (reader_optCheckChar (s, '$'))
4866 defstate = SS_DEFINED;
4867 isnull = NS_UNKNOWN;
4868 exitCode = XK_UNKNOWN;
4870 nullPred = qual_createUnknown ();
4874 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4875 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4876 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4877 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4878 advanceField (s); nullPred = qual_undump (s);
4881 if (reader_optCheckChar (s, '$'))
4884 globs = globSet_undefined;
4886 mods = sRefSet_undefined;
4888 else if (reader_optCheckChar (s, '^'))
4891 globs = globSet_undefined;
4893 mods = sRefSet_undefined;
4897 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4898 advanceField (s); globs = globSet_undump (s);
4899 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4900 advanceField (s); mods = sRefSet_undump (s);
4903 if (reader_optCheckChar (s, '$'))
4910 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4911 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4914 advanceField (s); access = typeIdSet_undump (s);
4917 ** Optional clauses: Start with @<code>:
4920 while (reader_optCheckChar (s, '@'))
4922 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4924 reader_checkChar (s, ':');
4925 warnclause = warnClause_undump (s);
4927 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4929 reader_checkChar (s, ':');
4930 specclauses = stateClauseList_undump (s);
4938 advanceName (s); name = reader_getStringWord (s);
4940 ue = uentry_makeFunctionBase (name, ct, access,
4943 ak, exp, defstate, isnull,
4944 exitCode, specc, nullPred,
4947 fileloc_copy (loc));
4948 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4955 advanceField (s); access = typeIdSet_undump (s);
4956 advanceName (s); name = reader_getStringWord (s);
4958 ue = uentry_makeIterBase (name, access, ct,
4959 fileloc_copy (loc));
4966 advanceField (s); access = typeIdSet_undump (s);
4967 advanceName (s); name = reader_getStringWord (s);
4969 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4979 if (reader_optCheckChar (s, '$'))
4981 val = multiVal_undefined;
4982 access = typeIdSet_undefined;
4983 nullstate = NS_UNKNOWN;
4987 advanceField (s); val = multiVal_undump (s);
4988 advanceField (s); access = typeIdSet_undump (s);
4989 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4992 advanceName (s); name = reader_getStringWord (s);
4994 ue = uentry_makeConstantBase (name, ct, access,
4995 nullstate, fileloc_copy (loc), val);
5004 advanceField (s); rtype = ctype_undump (s);
5005 advanceName (s); name = reader_getStringWord (s);
5006 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5010 llcontbuglit ("uentry_undump: invalid");
5011 ue = uentry_undefined;
5014 llcontbuglit ("uentry_undump: elips marker");
5015 ue = uentry_undefined;
5024 uentry_dump (uentry v)
5026 return (uentry_dumpAux (v, FALSE));
5030 uentry_dumpParam (uentry v)
5032 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5033 ("dump: %s", uentry_unparseFull (v)));
5035 return (uentry_dumpAux (v, TRUE));
5039 uentry_dumpAux (uentry v, bool isParam)
5041 llassert (uentry_isValid (v));
5042 llassert (!uentry_isGlobalMarker (v));
5044 DPRINTF (("Dump uentry: [%p]", v));
5045 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5050 llcontbuglit ("uentry_dump: invalid entry");
5051 return cstring_undefined;
5053 return (message ("!."));
5057 vkind vk = v->info->var->kind;
5058 sstate dss = sRef_getDefState (v->sref);
5059 nstate nst = sRef_getNullState (v->sref);
5060 alkind alk = sRef_getAliasKind (v->sref);
5061 exkind exk = sRef_getExKind (v->sref);
5062 chkind chk = v->info->var->checked;
5064 DPRINTF (("Dumping var"));
5066 if (dss == SS_UNKNOWN
5067 && nst == NS_UNKNOWN
5068 && alk == AK_IMPTEMP
5069 && exk == XO_UNKNOWN
5070 && chk == CH_UNKNOWN)
5072 sdump = cstring_makeLiteral ("$");
5074 else if (dss == SS_DEFINED
5075 && nst == NS_UNKNOWN
5076 && alk == AK_IMPTEMP
5077 && exk == XO_UNKNOWN
5078 && chk == CH_UNKNOWN)
5080 sdump = cstring_makeLiteral ("&");
5082 else if (dss == SS_UNKNOWN
5083 && nst == NS_UNKNOWN
5084 && alk == AK_UNKNOWN
5085 && exk == XO_UNKNOWN
5086 && chk == CH_UNKNOWN)
5088 sdump = cstring_makeLiteral ("^");
5090 else if (exk == XO_UNKNOWN
5091 && chk == CH_UNKNOWN)
5093 sdump = message ("%d@%d@%d&",
5100 sdump = message ("%d@%d@%d@%d@%d",
5111 return (message ("%q|@%d|%q#%s",
5112 ctype_dump (v->utype),
5115 isParam ? cstring_undefined : v->uname));
5119 return (message ("%q|%q#%s",
5120 ctype_dump (v->utype),
5122 isParam ? cstring_undefined : v->uname));
5128 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5130 exkind_unparse (sRef_getExKind (v->sref)),
5131 ctype_unparse (v->utype), (int) v->utype));
5134 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5135 ctype_dump (v->utype),
5136 ynm_unparseCode (v->info->datatype->abs),
5137 ynm_unparseCode (v->info->datatype->mut),
5138 (int) sRef_getDefState (v->sref),
5139 (int) sRef_getNullState (v->sref),
5140 (int) sRef_getAliasKind (v->sref),
5141 (int) sRef_getExKind (v->sref),
5142 ctype_dump (v->info->datatype->type),
5146 cstring sdump, gdump, adump, xdump;
5147 alkind alk = sRef_getAliasKind (v->sref);
5148 exkind exk = sRef_getExKind (v->sref);
5150 if (sRef_getDefState (v->sref) == SS_DEFINED
5151 && !nstate_isKnown (sRef_getNullState (v->sref))
5152 && !exitkind_isKnown (v->info->fcn->exitCode)
5153 && v->info->fcn->specialCode == SPC_NONE
5154 && qual_isUnknown (v->info->fcn->nullPred))
5156 sdump = cstring_makeLiteral ("$");
5160 sdump = message ("@%d@%d@%d@%d@%x",
5161 (int) sRef_getDefState (v->sref),
5162 (int) sRef_getNullState (v->sref),
5163 (int) v->info->fcn->exitCode,
5164 (int) v->info->fcn->specialCode,
5165 qual_dump (v->info->fcn->nullPred));
5168 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5170 gdump = cstring_makeLiteral ("$");
5172 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5173 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5175 gdump = cstring_makeLiteral ("^");
5179 gdump = message ("@%s@%q@%s@%q",
5180 bool_dump (uentry_hasGlobs (v)),
5181 globSet_dump (uentry_getGlobs (v)),
5182 bool_dump (uentry_hasMods (v)),
5183 sRefSet_dump (uentry_getMods (v)));
5186 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5188 adump = cstring_makeLiteral ("$");
5192 adump = message ("@%d@%d", (int) alk, (int) exk);
5195 xdump = cstring_undefined;
5197 if (uentry_hasWarning (v))
5199 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5202 if (uentry_hasStateClauseList (v))
5204 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5207 return (message ("%q%q%q%q@%q%q#%s",
5208 ctype_dump (v->utype),
5212 typeIdSet_dump (uentry_accessType (v)),
5217 return (message ("%q@%q#%s",
5218 ctype_dump (v->utype),
5219 typeIdSet_dump (v->info->iter->access),
5222 return (message ("%q@%q#%s",
5223 ctype_dump (v->utype),
5224 typeIdSet_dump (uentry_accessType (v)),
5231 if (multiVal_isUnknown (uentry_getConstantValue (v))
5232 && typeIdSet_isEmpty (uentry_accessType (v))
5233 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5235 sdump = cstring_makeLiteral ("$");
5239 sdump = message ("@%q@%q@%d",
5240 multiVal_dump (uentry_getConstantValue (v)),
5241 typeIdSet_dump (uentry_accessType (v)),
5242 (int) sRef_getNullState (v->sref));
5245 return (message ("%q%q#%s",
5246 ctype_dump (v->utype),
5253 return (message ("%q@%q#%s",
5254 ctype_dump (v->utype),
5255 ctype_dump (v->info->datatype->type), v->uname));
5262 uentry_unparseAbbrev (uentry v)
5264 if (!uentry_isVariable (v))
5266 llcontbuglit ("uentry_unparseAbbrev: not variable");
5267 return uentry_unparse (v);
5270 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5274 uentry_unparse (uentry v)
5278 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5279 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5281 st = uentry_getName (v);
5283 if (cstring_isDefined (st))
5285 return (ctype_unparseDeclaration (v->utype, st));
5290 return (cstring_copy (ctype_unparse (v->utype)));
5295 uentry_unparseFull (uentry v)
5297 if (uentry_isUndefined (v))
5299 return (cstring_makeLiteral ("<undefined>"));
5305 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5306 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5307 ctype_unparse (v->utype),
5308 fileloc_unparse (uentry_whereSpecified (v)),
5309 fileloc_unparse (uentry_whereDeclared (v)),
5310 fileloc_unparse (uentry_whereDefined (v)));
5312 DPRINTF (("uentry: %s", res));
5314 if (uentry_isDatatype (v))
5316 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5319 (ctype_isDefined (v->info->datatype->type)
5320 ? v->info->datatype->type : ctype_unknown),
5321 ynm_unparse (v->info->datatype->mut),
5322 ynm_unparse (v->info->datatype->abs),
5323 sRef_unparseState (v->sref));
5325 else if (uentry_isFunction (v))
5327 res = message ("%q / sref: %q / mods: %q / "
5328 "globs: %q / clauses: %q / pre: %q / post: %q",
5330 sRef_unparseFull (v->sref),
5331 sRefSet_unparse (v->info->fcn->mods),
5332 globSet_unparse (v->info->fcn->globs),
5333 stateClauseList_unparse (v->info->fcn->specclauses),
5334 functionConstraint_unparse (v->info->fcn->preconditions),
5335 functionConstraint_unparse (v->info->fcn->postconditions));
5337 else if (uentry_isIter (v))
5339 res = message ("%q / sref: %q",
5341 sRef_unparseFull (v->sref));
5343 else if (uentry_isVariable (v))
5345 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5347 sRef_unparseFull (v->sref),
5348 (int) v->info->var->kind,
5349 (int) v->info->var->defstate,
5350 (int) v->info->var->nullstate,
5352 DPRINTF (("sref: [%p]", v->sref));
5353 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5354 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5356 else if (uentry_isConstant (v))
5358 res = message ("%q = %q",
5359 res, multiVal_unparse (uentry_getConstantValue (v)));
5363 res = message ("%q :: %q", res, uentry_unparse (v));
5370 bool uentry_hasAccessType (uentry e)
5372 if (uentry_isValid (e))
5377 return (!typeIdSet_isEmpty (e->info->iter->access));
5379 return (!typeIdSet_isEmpty (e->info->enditer->access));
5381 return (!typeIdSet_isEmpty (e->info->fcn->access));
5384 return (!typeIdSet_isEmpty (e->info->uconst->access));
5393 typeIdSet uentry_accessType (uentry e)
5395 if (uentry_isValid (e))
5400 return (e->info->iter->access);
5402 return (e->info->enditer->access);
5404 return (e->info->fcn->access);
5407 return (e->info->uconst->access);
5413 return typeIdSet_undefined;
5417 uentry_isVariable (uentry e)
5419 return (uentry_isVar (e));
5423 uentry_isSpecified (uentry e)
5425 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5429 uentry_isReallySpecified (uentry e)
5431 return (uentry_isValid (e)
5432 && fileloc_isRealSpec (e->whereSpecified));
5436 uentry_isVar (uentry e)
5438 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5442 uentry_isFakeTag (uentry e)
5444 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5448 uentry_isDatatype (uentry e)
5450 return (!uentry_isUndefined (e) &&
5451 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5452 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5456 uentry_setAbstract (uentry e)
5460 llassert (uentry_isDatatype (e)
5461 && (ynm_isMaybe (e->info->datatype->abs)));
5463 oldid = ctype_typeId (e->info->datatype->type);
5464 e->info->datatype->abs = YES;
5465 e->info->datatype->type = ctype_createAbstract (oldid);
5469 uentry_setConcrete (uentry e)
5471 llassert (uentry_isDatatype (e)
5472 && (ynm_isMaybe (e->info->datatype->abs)));
5474 e->info->datatype->abs = NO;
5478 uentry_isAbstractDatatype (uentry e)
5480 return (uentry_isDatatype (e)
5481 && (ynm_isOn (e->info->datatype->abs)));
5485 uentry_isMaybeAbstract (uentry e)
5487 return (uentry_isDatatype (e)
5488 && (ynm_isMaybe (e->info->datatype->abs)));
5492 uentry_isMutableDatatype (uentry e)
5494 bool res = uentry_isDatatype (e)
5495 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5501 uentry_isRefCountedDatatype (uentry e)
5503 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5507 uentry_isParam (uentry u)
5509 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5510 || u->info->var->kind == VKYIELDPARAM));
5514 uentry_isExpandedMacro (uentry u)
5516 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5520 uentry_isSefParam (uentry u)
5522 return (uentry_isVariable (u)
5523 && (u->info->var->kind == VKSEFPARAM
5524 || u->info->var->kind == VKREFSEFPARAM
5525 || u->info->var->kind == VKSEFRETPARAM
5526 || u->info->var->kind == VKREFSEFRETPARAM));
5530 uentry_isRefParam (uentry u)
5532 return (uentry_isVariable (u)
5533 && (u->info->var->kind == VKREFPARAM
5534 || u->info->var->kind == VKREFYIELDPARAM
5535 || u->info->var->kind == VKREFSEFPARAM
5536 || u->info->var->kind == VKREFSEFRETPARAM));
5540 uentry_isAnyParam (uentry u)
5542 return (uentry_isVariable (u)
5543 && ((u->info->var->kind == VKPARAM)
5544 || (u->info->var->kind == VKSEFPARAM)
5545 || (u->info->var->kind == VKYIELDPARAM)
5546 || (u->info->var->kind == VKRETPARAM)
5547 || (u->info->var->kind == VKSEFRETPARAM)));
5551 uentry_getDefState (uentry u)
5553 if (uentry_isValid (u))
5555 return (sRef_getDefState (u->sref));
5559 return (SS_UNKNOWN);
5564 uentry_isOut (uentry u)
5566 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5567 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5571 uentry_isPartial (uentry u)
5573 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5574 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5578 uentry_isStateSpecial (uentry u)
5580 return ((uentry_isVariable (u)
5581 && (u->info->var->defstate == SS_SPECIAL))
5582 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5585 exitkind uentry_getExitCode (uentry ue)
5587 if (uentry_isFunction (ue))
5589 return ue->info->fcn->exitCode;
5597 qual uentry_nullPred (uentry u)
5599 llassert (uentry_isRealFunction (u));
5601 if (uentry_isFunction (u))
5603 return (u->info->fcn->nullPred);
5607 return qual_createUnknown ();
5612 ** Note for variables, this is checking the declared state, not the current state.
5616 uentry_possiblyNull (uentry u)
5618 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5619 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5623 uentry_getAliasKind (uentry u)
5625 if (uentry_isValid (u))
5627 return (sRef_getAliasKind (uentry_getSref (u)));
5636 uentry_getExpKind (uentry u)
5638 if (uentry_isValid (u))
5640 return (sRef_getExKind (uentry_getSref (u)));
5649 uentry_isIter (uentry e)
5651 return (!uentry_isUndefined (e) && e->ukind == KITER);
5655 uentry_isEndIter (uentry e)
5657 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5661 uentry_isRealFunction (uentry e)
5663 return (uentry_isFunction (e) ||
5664 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5668 uentry_hasName (uentry e)
5670 if (uentry_isValid (e))
5672 cstring s = e->uname;
5674 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5675 || uentry_isFakeTag (e)));
5684 ** Returns true for fake tags.
5685 ** This is used for dumping the library
5688 bool uentry_hasRealName (uentry e)
5690 return (uentry_isValid (e)
5691 && cstring_isNonEmpty (e->uname)
5692 && !uentry_isGlobalMarker (e));
5696 /*@observer@*/ globSet
5697 uentry_getGlobs (uentry l)
5699 if (uentry_isInvalid (l))
5701 return globSet_undefined;
5704 if (l->ukind != KFCN)
5706 if (l->ukind != KITER && l->ukind != KENDITER)
5708 if (l->ukind == KVAR)
5710 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5712 ekind_unparse (l->ukind)));
5716 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5718 ekind_unparse (l->ukind)));
5721 return globSet_undefined;
5724 return l->info->fcn->globs;
5727 /*@observer@*/ sRefSet
5728 uentry_getMods (uentry l)
5730 llassert (uentry_isValid (l));
5732 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5734 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5735 return sRefSet_undefined;
5738 return l->info->fcn->mods;
5742 uentry_getKind (uentry e)
5744 llassert (uentry_isValid (e));
5749 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5751 llassert (uentry_isEitherConstant (e));
5752 return (sRef_getValue (e->sref));
5755 /*@observer@*/ uentryList
5756 uentry_getParams (uentry l)
5758 if (uentry_isInvalid (l)) return uentryList_undefined;
5765 ctype ct = l->utype;
5767 if (ctype_isFunction (ct))
5769 return (ctype_argsFunction (ct));
5773 return uentryList_undefined;
5778 ctype ct = l->utype;
5780 llassert (ctype_isFunction (ct));
5781 return (ctype_argsFunction (ct));
5788 /*@observer@*/ cstring
5789 uentry_rawName (uentry e)
5791 if (uentry_isValid (e))
5797 return cstring_undefined;
5802 uentry_getOptName (uentry e)
5804 cstring s = uentry_getName (e);
5806 if (cstring_isDefined (s))
5808 s = cstring_appendChar (s, ' ');
5815 uentry_getName (uentry e)
5817 cstring ret = cstring_undefined;
5819 if (uentry_isValid (e))
5821 if (uentry_isAnyTag (e))
5823 ret = fixTagName (e->uname);
5825 else if (uentry_isAnyParam (e))
5827 ret = cstring_copy (fixParamName (e->uname));
5831 ret = cstring_copy (e->uname);
5838 cstring uentry_observeRealName (uentry e)
5840 cstring ret = cstring_undefined;
5842 if (uentry_isValid (e))
5844 if (uentry_isAnyTag (e))
5846 if (isFakeTag (e->uname))
5848 ret = cstring_undefined;
5852 ret = plainTagName (e->uname);
5855 else if (uentry_isAnyParam (e))
5857 ret = fixParamName (e->uname);
5868 cstring uentry_getRealName (uentry e)
5870 if (uentry_isValid (e))
5872 if (uentry_isAnyTag (e))
5874 return (cstring_undefined);
5881 return cstring_undefined;
5884 ctype uentry_getType (uentry e)
5886 if (uentry_isValid (e))
5892 return ctype_unknown;
5896 fileloc uentry_whereLast (uentry e)
5900 if (uentry_isInvalid (e))
5902 return fileloc_undefined;
5905 loc = e->whereDefined;
5907 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5912 loc = uentry_whereDeclared (e);
5914 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5919 loc = uentry_whereSpecified (e);
5923 fileloc uentry_whereEither (uentry e)
5925 if (uentry_isInvalid (e)) return fileloc_undefined;
5927 if (fileloc_isDefined (e->whereDefined)
5928 && !fileloc_isExternal (e->whereDefined))
5930 return e->whereDefined;
5932 else if (fileloc_isDefined (e->whereDeclared))
5934 return e->whereDeclared;
5938 return e->whereSpecified;
5942 fileloc uentry_whereSpecified (uentry e)
5944 if (uentry_isInvalid (e)) return fileloc_undefined;
5946 return (e->whereSpecified);
5949 fileloc uentry_whereDefined (uentry e)
5951 if (uentry_isInvalid (e)) return fileloc_undefined;
5953 return (e->whereDefined);
5956 fileloc uentry_whereDeclared (uentry e)
5958 if (uentry_isInvalid (e)) return fileloc_undefined;
5960 return (e->whereDeclared);
5963 /*@observer@*/ fileloc
5964 uentry_whereEarliest (uentry e)
5966 if (uentry_isInvalid (e)) return fileloc_undefined;
5968 if (fileloc_isDefined (e->whereSpecified))
5970 return (e->whereSpecified);
5972 else if (fileloc_isDefined (e->whereDeclared))
5974 return (e->whereDeclared);
5978 return e->whereDefined;
5983 uentry_setFunctionDefined (uentry e, fileloc loc)
5985 if (uentry_isValid (e))
5987 llassert (uentry_isFunction (e));
5989 if (fileloc_isUndefined (e->whereDeclared))
5991 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5994 if (!fileloc_isDefined (e->whereDefined))
5996 e->whereDefined = fileloc_update (e->whereDefined, loc);
6002 uentry_setDeclDef (uentry e, fileloc f)
6004 uentry_setDeclared (e, f);
6006 if (!uentry_isFunction (e)
6007 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6009 uentry_setDefined (e, f);
6014 uentry_setDeclaredForce (uentry e, fileloc f)
6016 llassert (uentry_isValid (e));
6017 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6021 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6023 llassert (uentry_isValid (e));
6024 fileloc_free (e->whereDeclared);
6025 e->whereDeclared = f;
6029 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6033 llassert (uentry_isValid (e));
6034 oldloc = e->whereDeclared;
6036 if (fileloc_isDefined (oldloc))
6038 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6040 e->whereDeclared = f;
6041 fileloc_free (oldloc);
6050 e->whereDeclared = f;
6051 fileloc_free (oldloc);
6056 uentry_setDeclared (uentry e, fileloc f)
6060 llassert (uentry_isValid (e));
6061 oldloc = e->whereDeclared;
6063 if (fileloc_isDefined (oldloc))
6065 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6067 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6076 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6081 uentry_clearDefined (uentry e)
6083 if (uentry_isValid (e))
6085 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6090 uentry_setDefined (uentry e, fileloc f)
6094 llassert (uentry_isValid (e));
6095 oldloc = e->whereDefined;
6097 if (fileloc_isDefined (oldloc))
6099 if (fileloc_isLib (oldloc)
6100 || fileloc_isImport (oldloc)
6101 || fileloc_isBuiltin (oldloc)
6102 || fileloc_isPreproc (oldloc))
6104 e->whereDefined = fileloc_update (e->whereDefined, f);
6108 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6114 if (optgenerror (FLG_REDEF,
6115 message ("%s %q redefined",
6116 ekind_capName (e->ukind),
6117 uentry_getName (e)),
6120 llgenindentmsg (message ("Previous definition of %q",
6121 uentry_getName (e)),
6129 e->whereDefined = fileloc_update (e->whereDefined, f);
6134 uentry_isCodeDefined (uentry e)
6136 llassert (uentry_isValid (e));
6138 return (fileloc_isDefined (e->whereDefined));
6142 uentry_isDeclared (uentry e)
6144 if (uentry_isValid (e))
6146 return (fileloc_isDefined (e->whereDeclared));
6152 sRef uentry_getSref (uentry e)
6154 /* not true, used for functions too (but shouldn't be? */
6155 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6157 if (uentry_isInvalid (e)) return sRef_undefined;
6162 sRef uentry_getOrigSref (uentry e)
6164 /*@i523*/ /* evans 2001-09-09 - need to fix this
6165 if (uentry_isValid (e))
6167 if (uentry_isVariable (e))
6169 return e->info->var->origsref;
6173 sRef sr = sRef_copy (uentry_getSref (e));
6175 sRef_resetState (sr);
6176 sRef_clearDerived (sr);
6182 return sRef_undefined;
6186 if (uentry_isValid (e))
6188 sRef sr = sRef_copy (uentry_getSref (e));
6190 sRef_resetState (sr);
6191 sRef_clearDerived (sr);
6193 if (uentry_isVariable (e))
6195 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6196 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6203 return sRef_undefined;
6208 ** requires: uentry e is not in a hashed symbol table
6212 uentry_setName (uentry e, /*@only@*/ cstring n)
6214 llassert (uentry_isValid (e));
6216 cstring_free (e->uname);
6221 uentry_setType (uentry e, ctype t)
6223 if (uentry_isValid (e))
6226 sRef_setType (e->sref, t);
6231 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6234 ctype rettype = ctype_unknown;
6236 llassert (uentry_isValid (ue));
6238 uentry_convertVarFunction (ue);
6239 llassert (uentry_isFunction (ue));
6241 rct = ctype_realType (ue->utype);
6243 if (ctype_isFunction (rct))
6245 rettype = ctype_getReturnType (rct);
6248 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6252 uentry_setRefParam (uentry e)
6254 if (!uentry_isVar (e))
6256 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6260 if (e->info->var->kind == VKSEFPARAM)
6262 e->info->var->kind = VKREFSEFPARAM;
6264 else if (e->info->var->kind == VKSEFRETPARAM)
6266 e->info->var->kind = VKREFSEFRETPARAM;
6268 else if (e->info->var->kind == VKYIELDPARAM)
6270 e->info->var->kind = VKREFYIELDPARAM;
6274 e->info->var->kind = VKREFPARAM;
6280 uentry_setParam (uentry e)
6282 if (!uentry_isVar (e))
6284 if (uentry_isElipsisMarker (e))
6290 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6297 if (e->info->var->kind == VKYIELDPARAM
6298 || e->info->var->kind == VKSEFPARAM
6299 || e->info->var->kind == VKSEFRETPARAM)
6305 e->info->var->kind = VKPARAM;
6309 e->uname = makeParam (e->uname);
6310 cstring_free (oldname);
6315 uentry_setSref (uentry e, sRef s)
6317 if (uentry_isValid (e))
6319 if (sRef_isValid (e->sref))
6321 sRef_mergeStateQuietReverse (e->sref, s);
6325 e->sref = sRef_saveCopy (s);
6331 uentry_getAbstractType (uentry e)
6333 llassert (uentry_isDatatype (e));
6336 ** This assertion removed.
6337 ** Okay to have undefined type, for system types
6339 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6340 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6345 if (ctype_isUndefined (e->info->datatype->type))
6347 return ctype_unknown;
6351 ** Sadly, a kludge...
6354 if (ctype_isUserBool (e->info->datatype->type)) {
6358 return e->info->datatype->type;
6361 ctype uentry_getRealType (uentry e)
6364 typeId uid = USYMIDINVALID;
6366 if (uentry_isInvalid (e))
6368 return ctype_unknown;
6371 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6373 if (uentry_isAnyTag (e))
6378 if (uentry_isAbstractType (e))
6380 ct = uentry_getAbstractType (e);
6382 if (ctype_isManifestBool (ct)) {
6386 llassert (ctype_isUA (ct));
6388 uid = ctype_typeId (ct);
6390 if (!context_hasAccess (uid))
6396 ct = uentry_getType (e);
6398 /* if (ctype_isUserBool (ct)) return ct; */
6400 if (ctype_isManifestBool (ct)) {
6404 if (ctype_isUA (ct))
6406 usymId iid = ctype_typeId (ct);
6408 if (usymId_equal (iid, uid))
6410 llcontbug (message ("uentry_getRealType: recursive type! %s",
6411 ctype_unparse (ct)));
6416 /* evs 2000-07-25: possible infinite recursion ? */
6417 uentry ue2 = usymtab_getTypeEntry (iid);
6421 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6422 return ctype_unknown;
6425 return uentry_getRealType (ue2);
6434 ctype uentry_getForceRealType (uentry e)
6437 typeId uid = USYMIDINVALID;
6439 if (uentry_isInvalid (e))
6441 return ctype_unknown;
6444 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6446 if (uentry_isAnyTag (e))
6451 if (uentry_isAbstractType (e))
6453 ct = uentry_getAbstractType (e);
6454 llassert (ctype_isUA (ct));
6456 uid = ctype_typeId (ct);
6457 /* no check for access! */
6460 ct = uentry_getType (e);
6462 /* evs 2000-07-25 */
6463 /* if (ctype_isUserBool (ct)) return ct; */
6465 if (ctype_isManifestBool (ct)) {
6469 if (ctype_isUA (ct))
6471 usymId iid = ctype_typeId (ct);
6473 if (usymId_equal (iid, uid))
6475 llcontbug (message ("uentry_getRealType: recursive type! %s",
6476 ctype_unparse (ct)));
6481 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6490 uentry uentry_nameCopy (cstring name, uentry e)
6492 uentry enew = uentry_alloc ();
6494 llassert (uentry_isValid (e));
6496 /* enew->shallowCopy = FALSE; */
6497 enew->ukind = e->ukind;
6499 enew->utype = e->utype;
6500 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6501 enew->whereDefined = fileloc_copy (e->whereDefined);
6502 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6503 enew->sref = sRef_copy (e->sref);
6504 enew->used = e->used;
6506 enew->isPrivate = e->isPrivate;
6507 enew->hasNameError = FALSE;
6509 enew->uses = filelocList_new ();
6510 enew->warn = warnClause_undefined;
6512 enew->storageclass = e->storageclass;
6513 enew->info = uinfo_copy (e->info, e->ukind);
6519 uentry_setDatatype (uentry e, usymId uid)
6521 llassert (uentry_isDatatype (e));
6523 if (uentry_isAbstractType (e))
6525 e->info->datatype->type = ctype_createAbstract (uid);
6529 e->info->datatype->type = ctype_createUser (uid);
6534 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6535 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6538 llassert (uentry_isValid (e));
6540 if (fileloc_isSpec (f) || fileloc_isImport (f))
6542 e->whereSpecified = f;
6543 e->whereDeclared = fileloc_undefined;
6544 e->whereDefined = fileloc_undefined;
6548 e->whereSpecified = fileloc_undefined;
6549 e->whereDeclared = f;
6550 e->whereDefined = fileloc_undefined;
6553 llassert (fileloc_storable (f));
6557 ucinfo_free (/*@only@*/ ucinfo u)
6563 uvinfo_free (/*@only@*/ uvinfo u)
6565 /*drl7x added 6/29/01 */
6566 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6571 udinfo_free (/*@only@*/ udinfo u)
6577 ufinfo_free (/*@only@*/ ufinfo u)
6579 globSet_free (u->globs);
6580 sRefSet_free (u->mods);
6581 stateClauseList_free (u->specclauses);
6586 uiinfo_free (/*@only@*/ uiinfo u)
6592 ueinfo_free (/*@only@*/ ueinfo u)
6597 static /*@only@*/ ucinfo
6598 ucinfo_copy (ucinfo u)
6600 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6601 ret->access = u->access;
6605 static /*@only@*/ uvinfo
6606 uvinfo_copy (uvinfo u)
6608 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6610 ret->kind = u->kind;
6611 ret->nullstate = u->nullstate;
6612 ret->defstate = u->defstate;
6613 ret->checked = u->checked;
6615 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6617 /* drl added 07-02-001 */
6618 /* copy null terminated information */
6620 if (u->bufinfo != NULL)
6622 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6623 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6624 ret->bufinfo->size = u->bufinfo->size;
6625 ret->bufinfo->len = u->bufinfo->len;
6630 ret->bufinfo = NULL;
6636 static /*@only@*/ udinfo
6637 udinfo_copy (udinfo u)
6639 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6643 ret->type = u->type;
6648 static /*@only@*/ ufinfo
6649 ufinfo_copy (ufinfo u)
6651 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6653 ret->hasGlobs = u->hasGlobs;
6654 ret->hasMods = u->hasMods;
6655 ret->exitCode = u->exitCode;
6656 ret->specialCode = u->specialCode;
6657 ret->nullPred = u->nullPred;
6658 ret->access = u->access;
6659 ret->globs = globSet_newCopy (u->globs);
6660 ret->mods = sRefSet_newCopy (u->mods);
6661 ret->defparams = u->defparams;
6662 ret->specclauses = stateClauseList_copy (u->specclauses);
6664 ret->preconditions = functionConstraint_copy (u->preconditions);
6665 ret->postconditions = functionConstraint_copy (u->postconditions);
6670 static /*@only@*/ uiinfo
6671 uiinfo_copy (uiinfo u)
6673 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6675 ret->access = u->access;
6676 ret->globs = globSet_newCopy (u->globs);
6677 ret->mods = sRefSet_newCopy (u->mods);
6682 static /*@only@*/ ueinfo
6683 ueinfo_copy (ueinfo u)
6685 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6687 ret->access = u->access;
6692 uinfo_free (uinfo u, ekind kind)
6697 case KCONST: ucinfo_free (u->uconst); break;
6698 case KVAR: uvinfo_free (u->var); break;
6702 case KDATATYPE: udinfo_free (u->datatype); break;
6703 case KFCN: ufinfo_free (u->fcn); break;
6704 case KITER: uiinfo_free (u->iter); break;
6705 case KENDITER: ueinfo_free (u->enditer); break;
6706 case KELIPSMARKER: break;
6707 case KINVALID: break;
6713 static /*@only@*/ /*@null@*/ uinfo
6714 uinfo_copy (uinfo u, ekind kind)
6716 if (kind == KELIPSMARKER || kind == KINVALID)
6722 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6727 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6728 case KVAR: ret->var = uvinfo_copy (u->var); break;
6732 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6733 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6734 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6735 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6743 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6745 filelocList_free (e->uses);
6746 cstring_free (e->uname);
6748 uinfo_free (e->info, e->ukind);
6750 fileloc_free (e->whereSpecified);
6751 fileloc_free (e->whereDefined);
6752 fileloc_free (e->whereDeclared);
6754 warnClause_free (e->warn);
6760 extern void uentry_markOwned (/*@owned@*/ uentry u)
6762 sfreeEventually (u);
6766 uentry_free (/*@only@*/ uentry e)
6768 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6770 uentry_reallyFree (e);
6775 ** For uentry's in the global or file scope
6779 uentry_freeComplete (/*@only@*/ uentry e)
6781 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6783 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6784 /*@i@*/ sRef_free (e->sref);
6785 e->sref = sRef_undefined;
6786 uentry_reallyFree (e);
6791 ** requires old->kind != new->kind, old->uname = new->uname
6795 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6797 llassert (uentry_isValid (old));
6798 llassert (uentry_isValid (unew));
6800 if (uentry_isEitherConstant (unew)
6801 && (fileloc_isPreproc (uentry_whereDeclared (old))
6802 || ctype_isUnknown (old->utype))
6803 && !uentry_isSpecified (old))
6811 if (!uentry_isDeclared (old))
6813 if (uentry_isSpecified (old))
6815 if (uentry_isSpecified (unew))
6817 llbuglit ("Respecification!");
6819 else if (uentry_isDeclared (unew))
6823 message ("%s %q inconsistently declared as %s: %t",
6824 ekind_capName (old->ukind),
6825 uentry_getName (unew),
6826 ekind_unparseLong (unew->ukind),
6828 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6830 uentry_showWhereLastKind (old);
6842 message ("%s %q inconsistently declared as %s: %t",
6843 ekind_capName (old->ukind),
6844 uentry_getName (unew),
6845 ekind_unparseLong (unew->ukind),
6847 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6849 uentry_showWhereLastKind (old);
6855 llassert (uentry_isDeclared (unew));
6857 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6858 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6862 message ("%s %q inconsistently redeclared as %s",
6863 ekind_capName (old->ukind),
6864 uentry_getName (unew),
6865 ekind_unparseLong (unew->ukind)),
6866 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6868 uentry_showWhereLastKind (old);
6874 uentry_updateInto (old, unew);
6878 ** def is the definition of spec, modifies spec
6880 ** reports any inconsistencies
6881 ** returns the summary of all available information
6882 ** if spec and def are inconsistent, def is returned
6886 uentry_showWhereLast (uentry spec)
6888 if (uentry_isValid (spec))
6890 if (fileloc_isDefined (spec->whereDefined)
6891 && !fileloc_isLib (spec->whereDefined)
6892 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6894 llgenindentmsg (message ("Previous definition of %q: %t",
6895 uentry_getName (spec),
6896 uentry_getType (spec)),
6897 uentry_whereDefined (spec));
6899 else if (uentry_isDeclared (spec))
6901 llgenindentmsg (message ("Previous declaration of %q: %t",
6902 uentry_getName (spec),
6903 uentry_getType (spec)),
6904 uentry_whereDeclared (spec));
6906 else if (uentry_isSpecified (spec))
6908 if (uentry_hasName (spec))
6910 llgenindentmsg (message ("Specification of %q: %t",
6911 uentry_getName (spec),
6912 uentry_getType (spec)),
6913 uentry_whereSpecified (spec));
6917 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6918 uentry_whereSpecified (spec));
6923 /* nothing to show */
6929 uentry_showWhereLastKind (uentry spec)
6931 if (uentry_isValid (spec))
6933 if (fileloc_isDefined (spec->whereDefined)
6934 && !fileloc_isLib (spec->whereDefined)
6935 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6937 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6938 uentry_getName (spec),
6939 ekind_unparseLong (spec->ukind),
6940 uentry_getType (spec)),
6941 uentry_whereDefined (spec));
6943 else if (uentry_isDeclared (spec))
6945 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6946 uentry_getName (spec),
6947 ekind_unparseLong (spec->ukind),
6948 uentry_getType (spec)),
6949 uentry_whereDeclared (spec));
6951 else if (uentry_isSpecified (spec))
6953 if (uentry_hasName (spec))
6955 llgenindentmsg (message ("Specification of %q as %s: %t",
6956 uentry_getName (spec),
6957 ekind_unparseLong (spec->ukind),
6958 uentry_getType (spec)),
6959 uentry_whereSpecified (spec));
6963 llgenindentmsg (message ("Specification as %s: %t",
6964 ekind_unparseLong (spec->ukind),
6965 uentry_getType (spec)),
6966 uentry_whereSpecified (spec));
6971 /* nothing to show */
6977 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6979 fileloc loc = uentry_whereDefined (ce);
6981 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6983 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6987 loc = uentry_whereSpecified (ce);
6989 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6991 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6996 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6998 if (uentry_isDeclared (spec))
7000 llgenindentmsg (message ("Previous declaration of %q: %q",
7001 uentry_getName (spec), extra),
7002 uentry_whereDeclared (spec));
7004 else if (uentry_isSpecified (spec))
7006 llgenindentmsg (message ("Specification of %q: %q",
7007 uentry_getName (spec), extra),
7008 uentry_whereSpecified (spec));
7012 cstring_free (extra);
7017 uentry_showWhereDeclared (uentry spec)
7019 if (uentry_isDeclared (spec))
7021 if (uentry_hasName (spec))
7023 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7024 uentry_whereDeclared (spec));
7028 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7031 else if (uentry_isSpecified (spec))
7033 if (uentry_hasName (spec))
7035 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7036 uentry_whereSpecified (spec));
7040 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7045 /* nothing to show */
7051 uentry_showWhereAny (uentry spec)
7053 if (uentry_isDeclared (spec))
7055 if (uentry_hasName (spec))
7057 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7058 uentry_whereDeclared (spec));
7062 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7065 else if (uentry_isSpecified (spec))
7067 if (uentry_hasName (spec))
7069 llgenindentmsg (message ("Specification of %q",
7070 uentry_getName (spec)),
7071 uentry_whereSpecified (spec));
7075 llgenindentmsg (cstring_makeLiteral ("Specification"),
7076 uentry_whereSpecified (spec));
7079 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7081 if (uentry_hasName (spec))
7083 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7084 uentry_whereDefined (spec));
7088 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7093 /* nothing to show */
7098 uentry_showWhereDefined (uentry spec)
7100 if (uentry_isCodeDefined (spec))
7102 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7103 uentry_whereDefined (spec));
7108 uentry_showWhereLastPlain (uentry spec)
7110 if (uentry_isDeclared (spec))
7112 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7113 uentry_whereDeclared (spec));
7115 else if (uentry_isSpecified (spec))
7117 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7118 uentry_whereSpecified (spec));
7126 uentry_showWhereLastVal (uentry spec, cstring val)
7128 if (uentry_isDeclared (spec))
7130 llgenindentmsg (message ("Previous declaration of %q: %s",
7131 uentry_getName (spec), val),
7132 uentry_whereDeclared (spec));
7134 else if (uentry_isSpecified (spec))
7136 llgenindentmsg (message ("Specification of %q: %s",
7137 uentry_getName (spec), val),
7138 uentry_whereSpecified (spec));
7146 uentry_showWhereSpecified (uentry spec)
7148 if (uentry_isSpecified (spec))
7150 if (uentry_hasName (spec))
7152 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7153 uentry_whereSpecified (spec));
7157 llgenindentmsg (cstring_makeLiteral ("Specification"),
7158 uentry_whereSpecified (spec));
7161 else if (uentry_isDeclared (spec))
7163 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7164 uentry_whereDeclared (spec));
7168 /* nothing to show */
7173 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7175 if (uentry_isSpecified (spec))
7177 if (uentry_hasName (spec))
7179 llgenindentmsg (message ("Specification of %q: %q",
7180 uentry_getName (spec), s),
7181 uentry_whereSpecified (spec));
7185 llgenindentmsg (message ("Specification: %q", s),
7186 uentry_whereSpecified (spec));
7189 else if (uentry_isDeclared (spec))
7191 llgenindentmsg (message ("Declaration of %q: %q",
7192 uentry_getName (spec), s),
7193 uentry_whereDeclared (spec));
7197 llgenindentmsg (message ("Previous: %q", s),
7198 uentry_whereLast (spec));
7207 checkStructConformance (uentry old, uentry unew)
7210 uentryList fold, fnew;
7213 ** requires: types of old and new are structs or unions
7216 llassert (uentry_isValid (old));
7217 llassert (uentry_isValid (unew));
7219 oldr = ctype_realType (old->utype);
7220 fold = ctype_getFields (oldr);
7222 newr = ctype_realType (unew->utype);
7223 fnew = ctype_getFields (newr);
7225 if (!uentryList_matchFields (fold, fnew))
7227 if (fileloc_equal (uentry_whereLast (old),
7228 uentry_whereLast (unew)))
7236 message ("%q %q %rdeclared with fields { %q }, %s "
7237 "with fields { %q }",
7238 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7239 uentry_getName (old),
7240 uentry_isDeclared (old),
7241 uentryList_unparseAbbrev (fnew),
7242 uentry_specOrDefName (old),
7243 uentryList_unparseAbbrev (fold)),
7244 uentry_whereDeclared (unew)))
7246 uentry_showWhereLastPlain (old);
7247 uentryList_showFieldDifference (fold, fnew);
7251 old->utype = unew->utype;
7256 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7259 ** requires old and new are enums
7262 ctype rold = ctype_realType (old->utype);
7263 ctype rnew = ctype_realType (unew->utype);
7264 enumNameList eold = ctype_elist (rold);
7265 enumNameList enew = ctype_elist (rnew);
7267 if (!enumNameList_match (eold, enew))
7271 message ("Enum %q declared with members { %q } but "
7272 "specified with members { %q }",
7273 uentry_getName (old),
7274 enumNameList_unparse (enew),
7275 enumNameList_unparse (eold)),
7276 uentry_whereDeclared (unew)))
7278 uentry_showWhereSpecified (old);
7279 old->utype = unew->utype;
7285 ** either oldCurrent or newCurrent may be undefined!
7289 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7290 uentry unew, uentry newCurrent, ctype newType,
7293 bool hasError = FALSE;
7295 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7297 if (uentry_hasName (newCurrent))
7299 hasError = optgenerror
7301 message ("Parameter %d, %q, of function %q has inconsistent type: "
7302 "declared %t, %s %t",
7303 paramno + 1, uentry_getName (newCurrent),
7304 uentry_getName (unew),
7305 newType, uentry_specOrDefName (old), oldType),
7306 uentry_whereDeclared (newCurrent));
7310 hasError = optgenerror
7312 message ("Parameter %d of function %q has inconsistent type: "
7313 "declared %t, %s %t",
7314 paramno + 1, uentry_getName (unew),
7315 newType, uentry_specOrDefName (old), oldType),
7316 uentry_whereDeclared (newCurrent));
7318 DPRINTF (("type: %s / %s",
7319 ctype_unparse (newType),
7320 ctype_unparse (ctype_realType (newType))));
7325 if (uentry_isDeclared (unew))
7327 hasError = optgenerror
7329 message ("Parameter %d of function %s has inconsistent type: "
7330 "declared %t, %s %t",
7331 paramno + 1, unew->uname,
7332 newType, uentry_specOrDefName (old), oldType),
7333 uentry_whereDeclared (unew));
7337 hasError = optgenerror
7339 message ("Parameter %d of function %s has inconsistent type: "
7340 "declared %t, %s %t",
7341 paramno + 1, unew->uname,
7342 newType, uentry_specOrDefName (old), oldType),
7343 uentry_whereDeclared (unew));
7349 DPRINTF (("Here: %s / %s",
7350 uentry_unparseFull (oldCurrent),
7351 uentry_unparseFull (newCurrent)));
7353 if (!uentry_isUndefined (oldCurrent))
7355 if (!uentry_isUndefined (newCurrent)
7356 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7358 uentry_showWhereLast (oldCurrent);
7362 uentry_showWhereLastPlain (old);
7365 uentry_setType (oldCurrent, newType);
7369 uentry_showWhereLastPlain (old);
7375 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7379 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7381 uentry_isDeclared (old),
7382 uentryList_size (uentry_getParams (unew)),
7383 uentry_specOrDefName (old),
7384 uentryList_size (uentry_getParams (old))),
7385 uentry_whereDeclared (unew)))
7387 uentry_showWhereLastPlain (old);
7392 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7396 message ("Function %s inconsistently %rdeclared to return %t",
7398 uentry_isDeclared (old),
7399 ctype_getReturnType (unew->utype)),
7400 uentry_whereDeclared (unew)))
7402 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7406 static cstring paramStorageName (uentry ue)
7408 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7411 static cstring fcnErrName (uentry ue)
7413 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7416 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7418 if (uentry_isVar (ue))
7420 return (checkedName (ue->info->var->checked));
7424 return (cstring_makeLiteralTemp ("<checked invalid>"));
7428 static cstring checkedName (chkind checked)
7432 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7433 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7434 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7435 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7436 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7442 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7447 if (uentry_isVar (unew))
7449 llassert (uentry_isVar (old));
7451 oldState = old->info->var->nullstate;
7452 newState = unew->info->var->nullstate;
7456 oldState = sRef_getNullState (old->sref);
7457 newState = sRef_getNullState (unew->sref);
7460 if (oldState == NS_ABSNULL)
7462 if (uentry_isVar (old))
7464 old->info->var->nullstate = newState;
7467 sRef_mergeNullState (old->sref, newState);
7469 else if (newState == NS_UNKNOWN)
7471 if (completeConform && newState != oldState
7472 && uentry_isReallySpecified (old))
7476 message ("%s %q specified as %s, but declared without %s qualifier",
7477 ekind_capName (unew->ukind),
7478 uentry_getName (unew),
7479 nstate_unparse (oldState),
7480 nstate_unparse (oldState)),
7481 uentry_whereDeclared (unew)))
7483 uentry_showWhereSpecified (old);
7487 if (uentry_isVar (unew))
7489 unew->info->var->nullstate = oldState;
7492 sRef_mergeNullState (unew->sref, oldState);
7494 else if (newState == NS_POSNULL)
7496 if (oldState == NS_MNOTNULL
7497 && (ctype_isUA (unew->utype)
7498 || (uentry_isFunction (unew)
7499 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7501 if (uentry_isVar (unew))
7503 unew->info->var->nullstate = oldState;
7506 sRef_mergeNullState (unew->sref, oldState);
7510 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7511 || oldState == NS_UNKNOWN)
7518 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7520 uentry_ekindName (unew),
7521 uentry_getName (unew),
7522 uentry_isDeclared (old),
7524 uentry_specOrDefName (old),
7525 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7526 uentry_whereDeclared (unew)))
7528 uentry_showWhereSpecified (old);
7533 if (uentry_isVar (old))
7535 old->info->var->nullstate = newState;
7538 sRef_mergeNullState (old->sref, newState);
7541 else if (newState == NS_MNOTNULL)
7543 if (oldState != NS_MNOTNULL)
7549 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7550 "%s without notnull qualifier",
7551 uentry_ekindName (unew),
7552 uentry_getName (unew),
7553 uentry_isDeclared (old),
7555 uentry_specOrDefName (old)),
7556 uentry_whereDeclared (unew)))
7558 uentry_showWhereSpecified (old);
7562 if (uentry_isVar (old))
7564 old->info->var->nullstate = newState;
7567 sRef_mergeNullState (old->sref, newState);
7572 if (uentry_isVar (unew))
7574 unew->info->var->nullstate = oldState;
7577 sRef_mergeNullState (unew->sref, oldState);
7582 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7583 bool mustConform, bool completeConform)
7589 if (uentry_isVar (old) && uentry_isVar (unew))
7591 oldState = old->info->var->defstate;
7592 newState = unew->info->var->defstate;
7597 oldState = sRef_getDefState (old->sref);
7598 newState = sRef_getDefState (unew->sref);
7601 if (newState != oldState
7602 && newState != SS_UNKNOWN
7603 && newState != SS_DEFINED)
7609 message ("%s %q inconsistently %rdeclared %s %s %s, "
7611 uentry_ekindName (unew),
7612 uentry_getName (unew),
7613 uentry_isDeclared (old),
7615 sstate_unparse (newState),
7616 paramStorageName (unew),
7617 uentry_specOrDefName (old),
7619 sstate_unparse (oldState),
7620 paramStorageName (unew)),
7621 uentry_whereDeclared (unew)))
7623 uentry_showWhereSpecified (old);
7627 if (vars) old->info->var->defstate = newState;
7628 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7633 && (newState != oldState) && (oldState != SS_DEFINED)
7634 && uentry_isReallySpecified (old))
7638 message ("%s %q specified as %s, but declared without %s qualifier",
7639 ekind_capName (unew->ukind),
7640 uentry_getName (unew),
7641 sstate_unparse (oldState),
7642 sstate_unparse (oldState)),
7643 uentry_whereDeclared (unew)))
7645 uentry_showWhereSpecified (old);
7649 if (vars) unew->info->var->defstate = oldState;
7650 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7655 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7656 bool mustConform, bool completeConform)
7661 oldKind = sRef_getAliasKind (old->sref);
7662 newKind = sRef_getAliasKind (unew->sref);
7664 if (alkind_isImplicit (newKind)
7665 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7667 if (completeConform && !alkind_equal (newKind, oldKind)
7668 && uentry_isReallySpecified (old))
7672 message ("%s %q specified as %s, but declared without "
7673 "explicit alias qualifier",
7674 ekind_capName (unew->ukind),
7675 uentry_getName (unew),
7676 alkind_unparse (oldKind)),
7677 uentry_whereDeclared (unew)))
7679 uentry_showWhereSpecified (old);
7684 ** This really shouldn't be necessary, but it is!
7685 ** Function params (?) use new here.
7688 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7692 if (alkind_isKnown (newKind))
7694 if (!alkind_equal (oldKind, newKind))
7696 if (alkind_isKnown (oldKind))
7701 message ("%s %q inconsistently %rdeclared %s %s storage, "
7703 uentry_ekindName (unew),
7704 uentry_getName (unew),
7705 uentry_isDeclared (old),
7707 alkind_unparse (newKind),
7708 uentry_specOrDefName (old),
7709 alkind_unparse (oldKind)),
7710 uentry_whereDeclared (unew)))
7712 uentry_showWhereSpecified (old);
7714 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7715 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7716 sRef_setAliasKind (old->sref, AK_ERROR,
7717 uentry_whereDeclared (unew));
7721 sRef_setAliasKind (old->sref, newKind,
7722 uentry_whereDeclared (unew));
7727 if (!(alkind_isImplicit (newKind)))
7730 !uentry_isFunction (unew) &&
7733 message ("%s %q inconsistently %rdeclared %s %s storage, "
7734 "implicitly %s as temp storage",
7735 uentry_ekindName (unew),
7736 uentry_getName (unew),
7737 uentry_isDeclared (old),
7739 alkind_unparse (newKind),
7740 uentry_specOrDefName (old)),
7741 uentry_whereDeclared (unew)))
7743 uentry_showWhereSpecified (old);
7747 sRef_setAliasKind (old->sref, newKind,
7748 uentry_whereDeclared (unew));
7750 else /* newKind is temp or refcounted */
7757 else /* newKind unknown */
7764 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7765 bool mustConform, bool completeConform)
7770 oldKind = sRef_getExKind (old->sref);
7771 newKind = sRef_getExKind (unew->sref);
7773 if (exkind_isKnown (newKind))
7775 if (oldKind != newKind)
7777 if (exkind_isKnown (oldKind))
7782 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7783 uentry_ekindName (unew),
7784 uentry_getName (unew),
7785 uentry_isDeclared (old),
7787 exkind_unparse (newKind),
7788 uentry_specOrDefName (old),
7789 exkind_unparse (oldKind)),
7790 uentry_whereDeclared (unew)))
7792 uentry_showWhereSpecified (old);
7795 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7802 message ("%s %q inconsistently %rdeclared %s %s, "
7803 "implicitly %s without exposure qualifier",
7804 uentry_ekindName (unew),
7805 uentry_getName (unew),
7806 uentry_isDeclared (old),
7808 exkind_unparse (newKind),
7809 uentry_specOrDefName (old)),
7810 uentry_whereDeclared (unew)))
7812 uentry_showWhereSpecified (old);
7815 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7821 if (completeConform && exkind_isKnown (oldKind)
7822 && uentry_isReallySpecified (old))
7826 message ("%s %q specified as %s, but declared without "
7827 "exposure qualifier",
7828 ekind_capName (unew->ukind),
7829 uentry_getName (unew),
7830 exkind_unparse (oldKind)),
7831 uentry_whereDeclared (unew)))
7833 uentry_showWhereSpecified (old);
7837 /* yes, this is necessary! (if its a param) */
7838 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7843 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7844 bool mustConform, /*@unused@*/ bool completeConform)
7846 valueTable newvals = sRef_getValueTable (unew->sref);
7848 if (valueTable_isDefined (newvals))
7850 DPRINTF (("Check meta state: %s -> %s",
7851 uentry_unparseFull (old),
7852 uentry_unparseFull (unew)));
7854 DPRINTF (("Check meta state refs: %s -> %s",
7855 sRef_unparseFull (old->sref),
7856 sRef_unparseFull (unew->sref)));
7858 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7861 ** Copy the new values into the old ref
7864 valueTable_elements (newvals, key, newval)
7866 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7867 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7869 llassert (metaStateInfo_isDefined (msinfo));
7871 if (stateValue_isUndefined (oldval))
7873 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7877 if (stateValue_isError (oldval))
7879 if (!stateValue_isError (newval))
7881 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7885 ; /* No change necessary. */
7890 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7892 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7898 if (!stateValue_isError (newval)
7899 && !stateValue_isImplicit (newval))
7901 if (uentry_hasName (unew)
7902 || !sRef_isParam (uentry_getSref (unew)))
7907 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7908 uentry_ekindName (unew),
7909 uentry_getName (unew),
7910 uentry_isDeclared (old),
7912 stateValue_unparseValue (newval, msinfo),
7913 uentry_specOrDefName (old),
7914 stateValue_unparseValue (oldval, msinfo)),
7915 uentry_whereDeclared (unew)))
7917 uentry_showWhereSpecified (old);
7925 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7926 uentry_ekindName (unew),
7927 sRef_getParam (uentry_getSref (unew)),
7928 uentry_isDeclared (old),
7930 stateValue_unparseValue (newval, msinfo),
7931 uentry_specOrDefName (old),
7932 stateValue_unparseValue (oldval, msinfo)),
7933 uentry_whereDeclared (unew)))
7935 uentry_showWhereSpecified (old);
7941 DPRINTF (("Updating!"));
7942 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7946 DPRINTF (("Values match"));
7950 } end_valueTable_elements ;
7955 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7956 /*@notnull@*/ uentry unew,
7957 bool mustConform, bool completeConform)
7959 checkDefState (old, unew, mustConform, completeConform);
7960 checkNullState (old, unew, mustConform, completeConform);
7961 checkAliasState (old, unew, mustConform, completeConform);
7962 checkExpState (old, unew, mustConform, completeConform);
7963 checkMetaState (old, unew, mustConform, completeConform);
7965 sRef_storeState (old->sref);
7966 sRef_storeState (unew->sref);
7970 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7972 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7977 llassert (uentry_isVar (old));
7978 llassert (uentry_isVar (unew));
7980 if (cstring_isEmpty (old->uname))
7982 cstring_free (old->uname);
7983 old->uname = cstring_copy (unew->uname);
7986 if (unew->info->var->kind == VKRETPARAM
7987 || unew->info->var->kind == VKSEFRETPARAM)
7989 if (old->info->var->kind != VKRETPARAM
7990 && old->info->var->kind != VKSEFRETPARAM)
7994 message ("Parameter %q inconsistently %rdeclared as "
7995 "returned parameter",
7996 uentry_getName (unew),
7997 uentry_isDeclared (old)),
7998 uentry_whereDeclared (unew)))
8000 uentry_showWhereSpecified (old);
8001 old->info->var->kind = unew->info->var->kind;
8007 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8009 if (old->info->var->kind != VKSEFPARAM
8010 && old->info->var->kind != VKSEFRETPARAM)
8014 message ("Parameter %qinconsistently %rdeclared as "
8016 uentry_getOptName (unew),
8017 uentry_isDeclared (old)),
8018 uentry_whereDeclared (unew)))
8020 uentry_showWhereSpecified (old);
8021 old->info->var->kind = unew->info->var->kind;
8026 if (old->info->var->kind == VKSPEC)
8028 old->info->var->kind = unew->info->var->kind;
8032 unew->info->var->kind = old->info->var->kind;
8035 if (unew->info->var->checked != CH_UNKNOWN
8036 && unew->info->var->checked != old->info->var->checked)
8038 if (old->info->var->checked == CH_UNKNOWN
8039 && !fileloc_isUser (uentry_whereLast (old)))
8047 message ("Variable %q inconsistently %rdeclared as "
8048 "%s parameter (was %s)",
8049 uentry_getName (unew),
8050 uentry_isDeclared (old),
8051 checkedName (unew->info->var->checked),
8052 checkedName (old->info->var->checked)),
8053 uentry_whereDeclared (unew)))
8055 uentry_showWhereSpecified (old);
8059 old->info->var->checked = unew->info->var->checked;
8064 && (old->info->var->checked != CH_UNKNOWN)
8065 && uentry_isReallySpecified (old))
8069 message ("%s %q specified as %s, but declared without %s qualifier",
8070 ekind_capName (unew->ukind),
8071 uentry_getName (unew),
8072 checkedName (old->info->var->checked),
8073 checkedName (old->info->var->checked)),
8074 uentry_whereDeclared (unew)))
8076 uentry_showWhereSpecified (old);
8080 unew->info->var->checked = old->info->var->checked;
8083 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8086 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8088 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8093 llassert (uentry_isVar (u1));
8094 llassert (uentry_isVar (u2));
8096 if (u1->info->var->kind != u2->info->var->kind) {
8097 if (u1->info->var->kind == VKSEFRETPARAM) {
8098 if (u2->info->var->kind == VKRETPARAM) {
8101 message ("Function types are inconsistent. Parameter %d is "
8102 "sef parameter, but non-sef parameter in "
8103 "assigned function: %s",
8104 paramno, exprNode_unparse (e)),
8106 } else if (u2->info->var->kind == VKSEFPARAM) {
8109 message ("Function types are inconsistent. Parameter %d is "
8110 "returns parameter, but non-returns parameter in "
8111 "assigned function: %s",
8112 paramno, exprNode_unparse (e)),
8117 message ("Function types are inconsistent. Parameter %d is "
8118 "sef returns parameter, but non-sef returns parameter in "
8119 "assigned function: %s",
8120 paramno, exprNode_unparse (e)),
8123 } else if (u1->info->var->kind == VKRETPARAM) {
8126 message ("Function types are inconsistent. Parameter %d is "
8127 "returns parameter, but non-returns parameter in "
8128 "assigned function: %s",
8129 paramno, exprNode_unparse (e)),
8131 } else if (u1->info->var->kind == VKSEFPARAM) {
8134 message ("Function types are inconsistent. Parameter %d is "
8135 "sef parameter, but non-sef parameter in "
8136 "assigned function: %s",
8137 paramno, exprNode_unparse (e)),
8140 if (u2->info->var->kind == VKSEFRETPARAM) {
8143 message ("Function types are inconsistent. Parameter %d is "
8144 "normal parameter, but sef returns parameter in "
8145 "assigned function: %s",
8146 paramno, exprNode_unparse (e)),
8148 } else if (u2->info->var->kind == VKSEFPARAM) {
8151 message ("Function types are inconsistent. Parameter %d is "
8152 "normal parameter, but sef parameter in "
8153 "assigned function: %s",
8154 paramno, exprNode_unparse (e)),
8156 } else if (u2->info->var->kind == VKRETPARAM) {
8159 message ("Function types are inconsistent. Parameter %d is "
8160 "normal parameter, but returns parameter in "
8161 "assigned function: %s",
8162 paramno, exprNode_unparse (e)),
8170 if (u1->info->var->defstate != u2->info->var->defstate)
8174 message ("Function types are inconsistent. Parameter %d is "
8175 "%s, but %s in assigned function: %s",
8177 sstate_unparse (u1->info->var->defstate),
8178 sstate_unparse (u2->info->var->defstate),
8179 exprNode_unparse (e)),
8183 if (u1->info->var->nullstate != u2->info->var->nullstate)
8187 message ("Function types are inconsistent. Parameter %d is "
8188 "%s, but %s in assigned function: %s",
8190 nstate_unparse (u1->info->var->nullstate),
8191 nstate_unparse (u2->info->var->nullstate),
8192 exprNode_unparse (e)),
8196 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8200 message ("Function types are inconsistent. Parameter %d is "
8201 "%s, but %s in assigned function: %s",
8203 alkind_unparse (sRef_getAliasKind (u1->sref)),
8204 alkind_unparse (sRef_getAliasKind (u2->sref)),
8205 exprNode_unparse (e)),
8209 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8213 message ("Function types are inconsistent. Parameter %d is "
8214 "%s, but %s in assigned function: %s",
8216 exkind_unparse (sRef_getExKind (u1->sref)),
8217 exkind_unparse (sRef_getExKind (u2->sref)),
8218 exprNode_unparse (e)),
8224 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8225 /*@notnull@*/ uentry unew,
8226 bool mustConform, /*@unused@*/ bool completeConform)
8228 uentryList oldParams = uentry_getParams (old);
8229 uentryList newParams = uentry_getParams (unew);
8230 ctype newType = unew->utype;
8231 ctype oldType = ctype_realType (old->utype);
8232 ctype oldRetType = ctype_unknown;
8233 ctype newRetType = ctype_unknown;
8235 DPRINTF (("Function conform: %s ==> %s",
8236 uentry_unparseFull (old),
8237 uentry_unparseFull (unew)));
8239 if (uentry_isForward (old))
8241 mustConform = FALSE;
8242 uentry_updateInto (old, unew);
8247 ** check return values
8250 if (ctype_isKnown (oldType))
8252 llassert (ctype_isFunction (oldType));
8253 oldRetType = ctype_getReturnType (oldType);
8256 if (ctype_isKnown (newType))
8258 llassert (ctype_isFunction (newType));
8259 newRetType = ctype_getReturnType (newType);
8262 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8263 && !ctype_matchDef (newRetType, oldRetType))
8265 if (mustConform) returnValueError (old, unew);
8269 if (ctype_isConj (newRetType))
8271 if (ctype_isConj (oldRetType))
8273 if (!ctype_sameAltTypes (newRetType, oldRetType))
8277 message ("Function %q inconsistently %rdeclared to "
8278 "return alternate types %s "
8279 "(types match, but alternates are not identical, "
8280 "so checking may not be correct)",
8281 uentry_getName (unew),
8282 uentry_isDeclared (old),
8283 ctype_unparse (newRetType)),
8284 uentry_whereDeclared (unew)))
8286 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8292 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8297 DPRINTF (("Before state: %s",
8298 uentry_unparseFull (old)));
8299 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8300 DPRINTF (("After state: %s",
8301 uentry_unparseFull (old)));
8303 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8305 if (exitkind_isKnown (unew->info->fcn->exitCode))
8309 message ("Function %q inconsistently %rdeclared using %s",
8310 uentry_getName (unew),
8311 uentry_isDeclared (old),
8312 exitkind_unparse (unew->info->fcn->exitCode)),
8313 uentry_whereDeclared (unew)))
8315 uentry_showWhereSpecified (old);
8320 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8324 if (!qual_isUnknown (unew->info->fcn->nullPred))
8326 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8330 message ("Function %q inconsistently %rdeclared using %s",
8331 uentry_getName (unew),
8332 uentry_isDeclared (old),
8333 qual_unparse (unew->info->fcn->nullPred)),
8334 uentry_whereDeclared (unew)))
8336 uentry_showWhereSpecified (old);
8342 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8345 if (unew->info->fcn->specialCode != SPC_NONE)
8347 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8351 message ("Function %q inconsistently %rdeclared using %s",
8352 uentry_getName (unew),
8353 uentry_isDeclared (old),
8354 specCode_unparse (unew->info->fcn->specialCode)),
8355 uentry_whereDeclared (unew)))
8357 uentry_showWhereSpecified (old);
8363 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8370 if (!uentryList_sameObject (oldParams, newParams)
8371 && (!uentryList_isMissingParams (oldParams)))
8373 if (!uentryList_isMissingParams (newParams))
8376 int nparams = uentryList_size (oldParams);
8377 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8379 if (nparams != uentryList_size (newParams))
8381 nargsError (old, unew);
8384 if (uentryList_size (newParams) < nparams)
8386 nparams = uentryList_size (newParams);
8389 while (paramno < nparams)
8391 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8392 uentry newCurrent = uentryList_getN (newParams, paramno);
8393 ctype oldCurrentType = uentry_getType (oldCurrent);
8394 ctype newCurrentType = uentry_getType (newCurrent);
8396 llassert (uentry_isValid (oldCurrent)
8397 && uentry_isValid (newCurrent));
8399 if (!uentry_isElipsisMarker (oldCurrent)
8400 && !uentry_isElipsisMarker (newCurrent))
8402 checkVarConformance (oldCurrent, newCurrent,
8403 mustConform, completeConform);
8408 if (uentry_hasName (oldCurrent)
8409 && uentry_hasName (newCurrent))
8411 cstring oldname = uentry_getName (oldCurrent);
8412 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8414 cstring nname = uentry_getName (newCurrent);
8417 if (cstring_isDefined (pfx)
8418 && cstring_equalPrefix (oldname, pfx))
8420 oname = cstring_suffix (oldname, cstring_length (pfx));
8425 /*@-branchstate@*/ } /*@=branchstate@*/
8427 if (cstring_isDefined (pfx)
8428 && cstring_equalPrefix (nname, pfx))
8430 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8435 /*@-branchstate@*/ } /*@=branchstate@*/
8437 if (!cstring_equal (oname, nnamefix))
8440 (FLG_DECLPARAMMATCH,
8441 message ("Definition parameter name %s does not match "
8442 "name of corresponding parameter in "
8445 uentry_whereLast (newCurrent)))
8447 uentry_showWhereLastPlain (oldCurrent);
8451 cstring_free (oldname);
8452 cstring_free (nname);
8456 if (!ctype_match (oldCurrentType, newCurrentType))
8458 paramTypeError (old, oldCurrent, oldCurrentType,
8459 unew, newCurrent, newCurrentType, paramno);
8463 if (ctype_isMissingParamsMarker (newCurrentType)
8464 || ctype_isElips (newCurrentType)
8465 || ctype_isMissingParamsMarker (oldCurrentType)
8466 || ctype_isElips (oldCurrentType))
8472 if (ctype_isConj (newCurrentType))
8474 if (ctype_isConj (oldCurrentType))
8476 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8480 message ("Parameter %q inconsistently %rdeclared with "
8481 "alternate types %s "
8482 "(types match, but alternates are not identical, "
8483 "so checking may not be correct)",
8484 uentry_getName (newCurrent),
8485 uentry_isDeclared (oldCurrent),
8486 ctype_unparse (newCurrentType)),
8487 uentry_whereDeclared (unew)))
8489 uentry_showWhereLastVal (oldCurrent,
8490 ctype_unparse (oldCurrentType));
8498 message ("Parameter %q inconsistently %rdeclared with "
8499 "alternate types %s",
8500 uentry_getName (newCurrent),
8501 uentry_isDeclared (oldCurrent),
8502 ctype_unparse (newCurrentType)),
8503 uentry_whereDeclared (unew)))
8505 uentry_showWhereLastVal (oldCurrent,
8506 ctype_unparse (oldCurrentType));
8513 if (ctype_isConj (oldCurrentType))
8515 uentry_setType (newCurrent, oldCurrentType);
8523 ** Forgot this! detected by lclint:
8524 ** uentry.c:1257,15: Suspected infinite loop
8530 if (!uentryList_isMissingParams (newParams))
8532 if (ctype_isConj (oldRetType))
8534 old->utype = ctype_makeFunction (oldRetType,
8535 uentryList_copy (newParams));
8539 old->utype = unew->utype;
8543 checkGlobalsConformance (old, unew, mustConform, completeConform);
8544 checkModifiesConformance (old, unew, mustConform, completeConform);
8546 DPRINTF (("Before list: %s",
8547 uentry_unparseFull (old)));
8549 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8551 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8556 message ("Function %q redeclared using special clauses (can only "
8557 "be used in first declaration)",
8558 uentry_getName (unew)),
8559 uentry_whereDeclared (unew)))
8561 uentry_showWhereLast (old);
8565 /*@i23 need checking @*/
8567 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8571 /*@i43 should be able to append? @*/
8573 stateClauseList_checkEqual (old, unew);
8574 stateClauseList_free (unew->info->fcn->specclauses);
8575 unew->info->fcn->specclauses = stateClauseList_undefined;
8579 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8581 if (fileloc_isUndefined (old->whereDeclared))
8583 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8585 else if (fileloc_isUndefined (unew->whereDeclared))
8587 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8596 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8600 llassert (uentry_isValid (ue));
8601 llassert (uentry_isEitherConstant (ue));
8603 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8604 uval = uentry_getConstantValue (ue);
8606 if (multiVal_isDefined (uval))
8608 if (multiVal_isDefined (m))
8610 if (!multiVal_equiv (uval, m))
8614 message ("%s %q defined with inconsistent value: %q",
8615 ekind_capName (ue->ukind),
8616 uentry_getName (ue),
8617 multiVal_unparse (m)),
8620 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8628 uentry_setConstantValue (ue, m);
8633 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8636 bool typeError = FALSE;
8638 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8640 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8644 DPRINTF (("Check struct conformance: %s / %s",
8645 uentry_unparseFull (old),
8646 uentry_unparseFull (unew)));
8647 checkStructConformance (old, unew);
8652 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8654 llbug (message ("struct tags: bad types: %t / %t",
8655 old->utype, unew->utype));
8659 else if (uentry_isEnumTag (old))
8661 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8663 if (mustConform) checkEnumConformance (old, unew);
8667 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8669 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8670 ctype_unparse (unew->utype)));
8674 else if (!ctype_match (old->utype, unew->utype))
8676 DPRINTF (("Type mismatch: %s / %s",
8677 ctype_unparse (old->utype),
8678 ctype_unparse (unew->utype)));
8680 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8682 ctype realt = ctype_realType (unew->utype);
8684 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8686 unew->utype = ctype_bool;
8692 typeError = optgenerror
8694 message ("%q defined as %s", uentry_getName (old),
8695 ctype_unparse (realt)),
8696 uentry_whereDeclared (unew));
8704 ctype oldr = ctype_realType (old->utype);
8705 ctype newr = ctype_realType (unew->utype);
8707 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8709 checkStructConformance (old, unew);
8711 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8713 checkStructConformance (old, unew);
8715 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8717 checkEnumConformance (old, unew);
8719 else if (uentry_isConstant (old)
8720 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8722 /* okay...for now! (should check the type is reset later... */
8726 DPRINTF (("YABA!"));
8729 message ("%s %q %rdeclared with inconsistent type: %t",
8730 ekind_capName (unew->ukind),
8731 uentry_getName (unew),
8732 uentry_isDeclared (old),
8734 uentry_whereDeclared (unew)))
8736 uentry_showWhereLast (old);
8752 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8753 /*@notnull@*/ uentry unew,
8754 bool mustConform, bool completeConform)
8756 if (ctype_isDefined (unew->info->datatype->type))
8759 ** bool is hard coded here, since it is built into LCL.
8760 ** For now, we're stuck with LCL's types.
8763 if (ctype_isDirectBool (old->utype) &&
8764 cstring_equalLit (unew->uname, "bool"))
8766 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8767 evs 2000-07-25: removed
8769 unew->utype = ctype_bool;
8772 if (ctype_isUnknown (old->info->datatype->type))
8774 old->info->datatype->type = unew->info->datatype->type;
8778 DPRINTF (("Old: %s / New: %s",
8779 uentry_unparseFull (old),
8780 uentry_unparseFull (unew)));
8781 DPRINTF (("Types: %s / %s",
8782 ctype_unparse (old->info->datatype->type),
8783 ctype_unparse (unew->info->datatype->type)));
8785 if (ctype_matchDef (old->info->datatype->type,
8786 unew->info->datatype->type))
8795 ("Type %q %s with inconsistent type: %t",
8796 uentry_getName (unew),
8797 uentry_reDefDecl (old, unew),
8798 unew->info->datatype->type),
8799 uentry_whereDeclared (unew)))
8801 uentry_showWhereLastExtra
8802 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8805 old->info->datatype->type = unew->info->datatype->type;
8810 if (unew->info->datatype->abs != MAYBE)
8812 if (ynm_isOff (old->info->datatype->abs)
8813 && ynm_isOn (unew->info->datatype->abs))
8815 if (!ctype_isDirectBool (old->utype))
8820 ("Datatype %q inconsistently %rdeclared as abstract type",
8821 uentry_getName (unew),
8822 uentry_isDeclared (old)),
8823 uentry_whereDeclared (unew)))
8825 uentry_showWhereLastPlain (old);
8829 else if (ynm_isOn (old->info->datatype->abs)
8830 && ynm_isOff (unew->info->datatype->abs))
8832 if (!ctype_isDirectBool (old->utype))
8837 ("Datatype %q inconsistently %rdeclared as concrete type",
8838 uentry_getName (unew),
8839 uentry_isDeclared (old)),
8840 uentry_whereDeclared (unew)))
8842 uentry_showWhereLastPlain (old);
8853 if (ynm_isOn (old->info->datatype->abs))
8855 old->sref = unew->sref;
8856 unew->info->datatype->mut = old->info->datatype->mut;
8859 && uentry_isReallySpecified (old))
8864 ("Datatype %q specified as abstract, "
8865 "but abstract annotation not used in declaration",
8866 uentry_getName (unew)),
8867 uentry_whereDeclared (unew)))
8869 uentry_showWhereLastPlain (old);
8875 unew->info->datatype->abs = old->info->datatype->abs;
8877 if (ynm_isMaybe (unew->info->datatype->mut))
8879 if (completeConform && ynm_isOff (old->info->datatype->mut)
8880 && uentry_isReallySpecified (old))
8885 ("Datatype %q specified as immutable, "
8886 "but immutable annotation not used in declaration",
8887 uentry_getName (unew)),
8888 uentry_whereDeclared (unew)))
8890 uentry_showWhereLastPlain (old);
8894 unew->info->datatype->mut = old->info->datatype->mut;
8896 else if (ynm_isMaybe (old->info->datatype->mut))
8898 old->info->datatype->mut = unew->info->datatype->mut;
8902 if (ynm_isOn (old->info->datatype->abs))
8904 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8908 message ("Datatype %q inconsistently %rdeclared as immutable",
8909 uentry_getName (unew),
8910 uentry_isDeclared (old)),
8911 uentry_whereDeclared (unew)))
8913 uentry_showWhereLastPlain (old);
8918 if (ynm_isOff (old->info->datatype->mut)
8919 && ynm_isOn (unew->info->datatype->mut))
8923 message ("Datatype %q inconsistently %rdeclared as mutable",
8924 uentry_getName (unew),
8925 uentry_isDeclared (old)),
8926 uentry_whereDeclared (unew)))
8928 uentry_showWhereLastPlain (old);
8933 old->info->datatype->mut = unew->info->datatype->mut;
8936 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8940 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8941 /*@notnull@*/ uentry unew,
8943 /*@unused@*/ bool completeConform)
8945 multiVal oldval = uentry_getConstantValue (old);
8946 multiVal newval = uentry_getConstantValue (unew);
8948 if (multiVal_isDefined (oldval))
8950 if (multiVal_isDefined (newval))
8952 if (!multiVal_equiv (oldval, newval))
8957 message ("%s %q %rdeclared with inconsistent value: %q",
8958 ekind_capName (unew->ukind),
8959 uentry_getName (unew),
8960 uentry_isDeclared (old),
8961 multiVal_unparse (newval)),
8962 uentry_whereDeclared (unew)))
8964 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8968 uentry_setConstantValue (unew, multiVal_copy (oldval));
8977 uentry_setConstantValue (old, multiVal_copy (newval));
8982 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8983 /*@notnull@*/ uentry unew, bool mustConform,
8984 bool completeConform)
8986 bool typeError = FALSE;
8987 bool fcnConformance = FALSE;
8989 if (!ekind_equal (unew->ukind, old->ukind))
8992 ** okay, only if one is a function and the other is
8993 ** a variable of type function.
8996 if (unew->ukind == KENUMCONST
8997 && old->ukind == KCONST)
8999 old->ukind = KENUMCONST;
9003 if (unew->ukind == KFCN
9004 && old->ukind == KCONST
9005 && ctype_isUnknown (old->utype))
9008 ** When a function is defined with an unparam macro
9011 uentry_updateInto (old, unew);
9015 if (uentry_isExpandedMacro (old)
9016 && uentry_isEitherConstant (unew))
9018 uentry_updateInto (old, unew);
9022 if (uentry_isEndIter (unew))
9024 if (ctype_isUnknown (old->utype))
9026 if (!uentry_isSpecified (old)
9027 && uentry_isCodeDefined (unew))
9029 if (!fileloc_withinLines (uentry_whereDefined (old),
9030 uentry_whereDeclared (unew), 2))
9031 { /* bogus! will give errors if there is too much whitespace */
9035 ("Iterator finalized name %q does not match name in "
9036 "previous iter declaration (should be end_%q). This iter "
9037 "is declared at %q",
9038 uentry_getName (unew),
9039 uentry_getName (old),
9040 fileloc_unparse (uentry_whereDefined (old))),
9041 uentry_whereDeclared (old));
9045 uentry_updateInto (old, unew);
9050 KindConformanceError (old, unew, mustConform);
9054 if (uentry_isFunction (unew))
9056 if (uentry_isVariable (old))
9058 if (!ctype_isUnknown (old->utype))
9060 if (ctype_isFunction (old->utype))
9062 uentry_makeVarFunction (old);
9063 checkFunctionConformance (old, unew, mustConform,
9065 fcnConformance = TRUE;
9069 KindConformanceError (old, unew, mustConform);
9074 if (uentry_isExpandedMacro (old))
9076 if (fileloc_isUndefined (unew->whereDefined))
9078 unew->whereDefined = fileloc_update (unew->whereDefined,
9082 uentry_updateInto (old, unew);
9083 old->used = unew->used = TRUE;
9088 /* undeclared identifier */
9089 old->utype = unew->utype;
9090 uentry_makeVarFunction (old);
9091 checkFunctionConformance (old, unew, FALSE, FALSE);
9092 fcnConformance = TRUE;
9098 KindConformanceError (old, unew, mustConform);
9101 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9103 if (!ctype_isUnknown (unew->utype))
9105 if (ctype_isFunction (unew->utype))
9107 uentry_makeVarFunction (unew);
9108 checkFunctionConformance (old, unew, mustConform, completeConform);
9109 fcnConformance = TRUE;
9113 KindConformanceError (old, unew, mustConform);
9118 KindConformanceError (old, unew, mustConform);
9123 KindConformanceError (old, unew, mustConform);
9129 ** check parameter lists for functions
9130 ** (before type errors, to get better messages
9133 if (uentry_isFunction (old))
9135 checkFunctionConformance (old, unew, mustConform, completeConform);
9136 fcnConformance = TRUE;
9140 if (!ctype_isUndefined (old->utype))
9142 typeError = checkTypeConformance (old, unew, mustConform);
9149 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9151 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9154 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9156 DPRINTF (("Check datatype: %s / %s",
9157 uentry_unparseFull (old),
9158 uentry_unparseFull (unew)));
9160 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9163 if (uentry_isVariable (old) && uentry_isVariable (unew))
9166 !ctype_matchDef (old->utype, unew->utype))
9171 ("Variable %q %s with inconsistent type (arrays and pointers are "
9172 "not identical in variable declarations): %t",
9173 uentry_getName (unew),
9174 uentry_reDefDecl (old, unew),
9176 uentry_whereDeclared (unew)))
9178 uentry_showWhereLast (old);
9181 ** Avoid repeated errors.
9184 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9186 old->whereDefined = fileloc_update (old->whereDefined,
9194 checkVarConformance (old, unew, mustConform, completeConform);
9199 /* old->utype = unew->utype; */
9203 if (ctype_isConj (old->utype))
9205 if (ctype_isConj (unew->utype))
9207 if (!ctype_sameAltTypes (old->utype, unew->utype))
9211 message ("%s %q inconsistently %rdeclared with "
9212 "alternate types %s "
9213 "(types match, but alternates are not identical, "
9214 "so checking may not be correct)",
9215 ekind_capName (uentry_getKind (old)),
9216 uentry_getName (unew),
9217 uentry_isDeclared (old),
9218 ctype_unparse (unew->utype)),
9219 uentry_whereDeclared (unew)))
9221 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9225 old->utype = unew->utype;
9232 if (ctype_isUnknown (old->utype))
9234 old->utype = unew->utype;
9239 if (unew->ukind == old->ukind)
9242 unew->info = uinfo_copy (old->info, old->ukind);
9245 sRef_storeState (old->sref);
9246 sRef_storeState (unew->sref);
9249 static void uentry_mergeConstraints (uentry spec, uentry def)
9251 if (uentry_isFunction (def))
9253 DPRINTF (("Here: %s / %s",
9254 uentry_unparseFull (spec),
9255 uentry_unparseFull (def)));
9256 /* evans 2001-07-21 */
9257 llassert (uentry_isFunction (spec));
9259 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9261 if (fileloc_isXHFile (uentry_whereLast (def)))
9263 llassert (uentry_isFunction (spec));
9264 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9265 def->info->fcn->preconditions);
9267 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9273 /* Check if the constraints are identical */
9278 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9279 uentry_getName (spec),
9280 functionConstraint_unparse (spec->info->fcn->preconditions)),
9281 uentry_whereLast (def)))
9283 uentry_showWhereSpecified (spec);
9286 functionConstraint_free (spec->info->fcn->preconditions);
9287 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9290 def->info->fcn->preconditions = functionConstraint_undefined;
9293 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9295 if (fileloc_isXHFile (uentry_whereLast (def)))
9297 llassert (uentry_isFunction (spec));
9298 DPRINTF (("Post: %s /++/ %s",
9299 functionConstraint_unparse (spec->info->fcn->postconditions),
9300 functionConstraint_unparse (def->info->fcn->postconditions)));
9301 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9302 def->info->fcn->postconditions);
9303 def->info->fcn->postconditions = functionConstraint_undefined;
9304 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9311 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9312 uentry_getName (spec),
9313 functionConstraint_unparse (spec->info->fcn->postconditions)),
9314 uentry_whereLast (def)))
9316 uentry_showWhereSpecified (spec);
9319 functionConstraint_free (spec->info->fcn->postconditions);
9320 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9321 def->info->fcn->postconditions = functionConstraint_undefined;
9328 ** modifies spec to reflect def, reports any inconsistencies
9332 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9334 llassert (uentry_isValid (spec));
9335 llassert (uentry_isValid (def));
9336 llassert (cstring_equal (spec->uname, def->uname));
9338 if (uentry_isFunction (def))
9340 if (uentry_isConstant (spec))
9342 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9343 uentry_makeConstantFunction (spec);
9347 uentry_convertVarFunction (spec);
9350 llassert (uentry_isFunction (spec));
9353 DPRINTF (("Merge entries: %s / %s",
9354 uentry_unparseFull (spec),
9355 uentry_unparseFull (def)));
9357 uentry_mergeConstraints (spec, def);
9359 uentry_checkConformance (spec, def, TRUE,
9360 context_getFlag (FLG_NEEDSPEC));
9362 DPRINTF (("Merge entries after conform: %s / %s",
9363 uentry_unparseFull (spec),
9364 uentry_unparseFull (def)));
9366 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9369 ** okay, declarations conform. Propagate extra information.
9372 uentry_setDefined (spec, uentry_whereDefined (def));
9373 uentry_setDeclared (spec, uentry_whereDeclared (def));
9375 if (uentry_isStatic (def))
9379 message ("%s %q specified, but declared as static",
9380 ekind_capName (def->ukind),
9381 uentry_getName (def)),
9382 uentry_whereDeclared (def)))
9384 uentry_showWhereSpecified (spec);
9389 spec->storageclass = def->storageclass;
9392 sRef_storeState (spec->sref);
9394 spec->used = def->used || spec->used;
9395 spec->hasNameError |= def->hasNameError;
9399 if (!spec->hasNameError)
9401 uentry_checkName (spec);
9410 ** Can't generate function redeclaration errors when the
9411 ** entries are merged, since we don't yet know if its the
9412 ** definition of the function.
9416 uentry_clearDecl (void)
9418 posRedeclared = uentry_undefined;
9419 fileloc_free (posLoc);
9420 posLoc = fileloc_undefined;
9424 uentry_checkDecl (void)
9426 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9428 llassert (fileloc_isDefined (posLoc));
9430 if (uentry_isCodeDefined (posRedeclared))
9432 if (optgenerror (FLG_REDECL,
9433 message ("%s %q declared after definition",
9434 ekind_capName (posRedeclared->ukind),
9435 uentry_getName (posRedeclared)),
9438 llgenindentmsg (message ("Definition of %q",
9439 uentry_getName (posRedeclared)),
9440 posRedeclared->whereDeclared);
9445 if (optgenerror (FLG_REDECL,
9446 message ("%s %q declared more than once",
9447 ekind_capName (posRedeclared->ukind),
9448 uentry_getName (posRedeclared)),
9451 llgenindentmsg (message ("Previous declaration of %q",
9452 uentry_getName (posRedeclared)),
9453 posRedeclared->whereDeclared);
9458 fileloc_free (posLoc);
9459 posLoc = fileloc_undefined;
9460 posRedeclared = uentry_undefined;
9464 ** Redefinition of old as unew.
9465 ** modifies old to reflect unew, reports any inconsistencies
9469 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9471 fileloc olddef = uentry_whereDeclared (old);
9472 fileloc unewdef = uentry_whereDeclared (unew);
9476 DPRINTF (("uentry merge: %s / %s",
9477 uentry_unparseFull (old),
9478 uentry_unparseFull (unew)));
9481 fileloc_isUndefined (olddef)
9482 && fileloc_isDefined (uentry_whereDefined (old))
9483 && !uentry_isExpandedMacro (old);
9485 if (!context_getFlag (FLG_INCONDEFSLIB)
9486 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9488 mustConform = FALSE;
9495 llassert (uentry_isValid (old));
9496 llassert (uentry_isValid (unew));
9497 llassert (cstring_equal (old->uname, unew->uname));
9499 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9501 if (uentry_isConstant (old))
9503 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9504 uentry_makeConstantFunction (old);
9508 uentry_convertVarFunction (old);
9511 llassert (uentry_isFunction (old));
9514 DPRINTF (("uentry merge: %s / %s",
9515 uentry_unparseFull (old),
9516 uentry_unparseFull (unew)));
9518 if (uentry_isExtern (unew))
9520 uentry_setUsed (old, unewdef);
9524 ** should check old one was extern!
9527 if (uentry_isStatic (old))
9529 if (!(uentry_isStatic (unew)))
9533 message ("%s %q shadows static declaration",
9534 ekind_capName (unew->ukind),
9535 uentry_getName (unew)),
9538 uentry_showWhereLast (old);
9543 uentry_setDeclDef (old, unewdef);
9546 else if (uentry_isStatic (unew))
9548 uentry_setDeclDef (old, unewdef);
9550 else if (uentry_isExtern (old))
9552 uentry_setDeclared (old, unewdef);
9556 if (!uentry_isExtern (unew)
9557 && !uentry_isForward (old)
9558 && !fileloc_equal (olddef, unewdef)
9559 && !fileloc_isUndefined (olddef)
9560 && !fileloc_isUndefined (unewdef)
9561 && !fileloc_isBuiltin (olddef)
9562 && !fileloc_isBuiltin (unewdef)
9563 && !uentry_isYield (old)
9564 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9566 if (uentry_isVariable (old) || uentry_isVariable (unew))
9568 ; /* will report redeclaration error later */
9572 if (fileloc_isDefined (uentry_whereDefined (old)))
9576 message ("%s %q defined more than once",
9577 ekind_capName (unew->ukind),
9578 uentry_getName (unew)),
9579 uentry_whereLast (unew)))
9582 (message ("Previous definition of %q",
9583 uentry_getName (old)),
9584 uentry_whereLast (old));
9587 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9589 uentry_updateInto (old, unew);
9590 old->sref = sRef_saveCopy (old->sref);
9598 if (fileloc_isLib (olddef)
9599 || fileloc_isUndefined (olddef)
9600 || fileloc_isImport (olddef))
9602 if (uentry_isExtern (unew))
9604 if (uentry_isExtern (old)
9605 || (fileloc_isDefined (uentry_whereDeclared (old))
9606 && (!fileloc_equal (uentry_whereDeclared (old),
9607 uentry_whereDefined (old)))))
9611 message ("%s %q declared more than once",
9612 ekind_capName (unew->ukind),
9613 uentry_getName (unew)),
9614 unew->whereDeclared))
9617 (message ("Previous declaration of %q",
9618 uentry_getName (old)),
9619 old->whereDeclared);
9623 uentry_setExtern (old);
9627 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9633 DPRINTF (("uentry merge: %s / %s",
9634 uentry_unparseFull (old),
9635 uentry_unparseFull (unew)));
9637 uentry_mergeConstraints (old, unew);
9638 DPRINTF (("uentry merge: %s / %s",
9639 uentry_unparseFull (old),
9640 uentry_unparseFull (unew)));
9642 uentry_checkConformance (old, unew, mustConform, FALSE);
9643 DPRINTF (("uentry merge: %s / %s",
9644 uentry_unparseFull (old),
9645 uentry_unparseFull (unew)));
9647 old->used = old->used || unew->used;
9648 old->uses = filelocList_append (old->uses, unew->uses);
9649 unew->uses = filelocList_undefined;
9651 sRef_storeState (old->sref);
9652 sRef_storeState (unew->sref);
9656 old->whereDefined = fileloc_update (old->whereDefined,
9660 DPRINTF (("here: %s", uentry_unparseFull (old)));
9663 ** No redeclaration errors for functions here, since we
9664 ** don't know if this is the definition of the function.
9667 if (fileloc_isUser (old->whereDeclared)
9668 && fileloc_isUser (unew->whereDeclared)
9669 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9670 && !fileloc_isDefined (unew->whereDefined))
9672 if (uentry_isFunction (old))
9674 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9675 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9679 if (optgenerror (FLG_REDECL,
9680 message ("%s %q declared more than once",
9681 ekind_capName (unew->ukind),
9682 uentry_getName (unew)),
9683 unew->whereDeclared))
9685 llgenindentmsg (message ("Previous declaration of %q",
9686 uentry_getName (old)),
9687 old->whereDeclared);
9692 if (fileloc_isUndefined (old->whereDefined))
9694 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9698 if (!context_processingMacros ()
9699 && fileloc_isUser (old->whereDefined)
9700 && fileloc_isUser (unew->whereDefined)
9701 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9703 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9705 if (uentry_isVariable (unew)
9706 && uentry_isExtern (unew))
9708 if (optgenerror (FLG_REDECL,
9709 message ("%s %q declared after definition",
9710 ekind_capName (unew->ukind),
9711 uentry_getName (unew)),
9712 unew->whereDeclared))
9714 llgenindentmsg (message ("Definition of %q",
9715 uentry_getName (old)),
9721 if (optgenerror (FLG_REDEF,
9722 message ("%s %q redefined",
9723 ekind_capName (unew->ukind),
9724 uentry_getName (unew)),
9725 unew->whereDefined))
9727 llgenindentmsg (message ("Previous definition of %q",
9728 uentry_getName (old)),
9736 if (uentry_isExternal (unew))
9738 old->whereDefined = fileloc_createExternal ();
9741 if (unew->hasNameError)
9743 old->hasNameError = TRUE;
9748 if (!old->hasNameError)
9750 uentry_checkName (old);
9753 DPRINTF (("After: %s", uentry_unparseFull (old)));
9754 llassert (!ctype_isUndefined (old->utype));
9758 uentry_copyState (uentry res, uentry other)
9760 llassert (uentry_isValid (res));
9761 llassert (uentry_isValid (other));
9763 res->used = other->used;
9765 res->info->var->kind = other->info->var->kind;
9766 res->info->var->defstate = other->info->var->defstate;
9767 res->info->var->nullstate = other->info->var->nullstate;
9768 res->info->var->checked = other->info->var->checked;
9770 sRef_copyState (res->sref, other->sref);
9774 uentry_sameKind (uentry u1, uentry u2)
9776 if (uentry_isValid (u1) && uentry_isValid (u2))
9778 if (uentry_isVar (u1) && uentry_isVar (u2))
9780 ctype c1 = u1->utype;
9781 ctype c2 = u2->utype;
9783 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9786 ** both functions, or both not functions
9789 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9793 return ((u1->ukind == u2->ukind));
9800 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9802 ekind okind = unew->ukind;
9803 llassert (uentry_isValid (unew));
9804 llassert (uentry_isValid (old));
9806 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9808 unew->ukind = old->ukind;
9809 llassert (cstring_equal (unew->uname, old->uname));
9810 unew->utype = old->utype;
9812 if (fileloc_isDefined (unew->whereSpecified)
9813 && !fileloc_isDefined (old->whereSpecified))
9815 ; /* Keep the old value */
9819 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9820 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9823 if (fileloc_isDefined (unew->whereDefined)
9824 && !fileloc_isDefined (old->whereDefined))
9826 ; /* Keep the old value */
9830 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9831 unew->whereDefined = fileloc_copy (old->whereDefined);
9834 if (fileloc_isDefined (unew->whereDeclared)
9835 && !fileloc_isDefined (old->whereDeclared))
9837 ; /* Keep the old value */
9841 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9842 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9845 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9847 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9848 unew->used = old->used;
9850 unew->isPrivate = old->isPrivate;
9851 unew->hasNameError = old->hasNameError;
9852 unew->uses = filelocList_append (unew->uses, old->uses);
9853 old->uses = filelocList_undefined;
9855 unew->storageclass = old->storageclass;
9856 uinfo_free (unew->info, okind);
9857 unew->info = uinfo_copy (old->info, old->ukind);
9862 uentry_copy (uentry e)
9864 if (uentry_isValid (e))
9866 uentry enew = uentry_alloc ();
9867 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9868 enew->ukind = e->ukind;
9869 enew->uname = cstring_copy (e->uname);
9870 enew->utype = e->utype;
9872 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9873 enew->whereDefined = fileloc_copy (e->whereDefined);
9874 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9876 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9877 enew->used = e->used;
9879 enew->isPrivate = e->isPrivate;
9880 enew->hasNameError = e->hasNameError;
9881 enew->uses = filelocList_undefined;
9883 enew->storageclass = e->storageclass;
9884 enew->info = uinfo_copy (e->info, e->ukind);
9885 enew->warn = warnClause_copy (e->warn);
9887 DPRINTF (("Here we are..."));
9888 DPRINTF (("original: %s", uentry_unparseFull (e)));
9889 DPRINTF (("copy: %s", uentry_unparse (enew)));
9890 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9895 return uentry_undefined;
9900 uentry_setState (uentry res, uentry other)
9902 llassert (uentry_isValid (res));
9903 llassert (uentry_isValid (other));
9905 llassert (res->ukind == other->ukind);
9906 llassert (res->ukind == KVAR);
9908 res->sref = sRef_saveCopy (other->sref);
9909 res->used = other->used;
9910 filelocList_free (res->uses);
9911 res->uses = other->uses;
9912 other->uses = filelocList_undefined;
9913 res->lset = other->lset;
9917 uentry_mergeUses (uentry res, uentry other)
9919 llassert (uentry_isValid (res));
9920 llassert (uentry_isValid (other));
9922 res->used = other->used || res->used;
9923 res->lset = other->lset || res->lset;
9924 res->uses = filelocList_append (res->uses, other->uses);
9925 other->uses = filelocList_undefined;
9930 ** This is a really ugly routine.
9932 ** gack...fix this one day.
9937 ** >> res is the false branch, other is the true branch (or continuation)
9939 ** >> res is the true branch, other is the false branch (or continutation)
9946 ** References not effected by res are propagated from other.
9950 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9951 bool flip, clause cl, fileloc loc)
9955 message ("%s %q is %s %s, but %s %s.",
9956 ekind_capName (res->ukind), uentry_getName (res),
9957 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9958 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9961 if (sRef_isDead (res->sref))
9963 sRef_showStateInfo (res->sref);
9965 else if (sRef_isKept (res->sref))
9967 sRef_showAliasInfo (res->sref);
9969 else /* dependent */
9971 sRef_showAliasInfo (res->sref);
9972 sRef_showAliasInfo (other->sref);
9975 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9979 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
9981 alkind rk = sRef_getAliasKind (rs);
9982 alkind ok = sRef_getAliasKind (os);
9984 if (alkind_isError (rk) || alkind_isError (ok))
9990 return ((sRef_isDead (rs)
9991 || (alkind_isKept (rk) && !alkind_isKept (ok))
9992 || (alkind_isDependent (rk)
9993 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9994 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9999 branchStateAltError (/*@notnull@*/ uentry res,
10000 /*@notnull@*/ uentry other, bool flip,
10001 clause cl, fileloc loc)
10005 message ("%s %q is %s %s, but %s %s.",
10006 ekind_capName (res->ukind), uentry_getName (res),
10007 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10008 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10011 if (sRef_isDead (other->sref))
10013 sRef_showStateInfo (other->sref);
10017 sRef_showAliasInfo (other->sref);
10020 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10021 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10023 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10024 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10029 ** A reference is relevant for certain checks, only if it
10030 ** is not definitely null on this path (but not declared
10031 ** to always be null.)
10034 static bool uentry_relevantReference (sRef sr, bool flip)
10036 if (sRef_isKept (sr) || sRef_isDependent (sr))
10044 return !sRef_definitelyNullContext (sr);
10048 return !sRef_definitelyNullAltContext (sr);
10054 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
10055 bool mustReturn, bool flip, bool opt,
10058 sRef rs = res->sref;
10059 sRef os = other->sref;
10061 DPRINTF (("Merge alias states: %s / %s",
10062 uentry_unparseFull (res),
10063 uentry_unparseFull (other)));
10065 if (sRef_isValid (rs))
10069 if (uentry_incompatibleMemoryStates (rs, os))
10071 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10072 sRef_unparseFull (rs), sRef_unparseFull (os)));
10074 if (sRef_isThroughArrayFetch (rs)
10075 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10077 if (sRef_isKept (rs) || sRef_isKept (os))
10079 sRef_maybeKill (rs, loc);
10081 else if (sRef_isPossiblyDead (os))
10083 sRef_maybeKill (rs, loc);
10092 if (uentry_relevantReference (os, flip))
10094 if (sRef_isLocalParamVar (rs)
10095 && (sRef_isLocalState (os)
10096 || sRef_isDependent (os)))
10098 if (sRef_isDependent (rs))
10100 sRef_setDependent (os, loc);
10104 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10109 branchStateError (res, other, flip, cl, loc);
10114 if (sRef_isKept (rs))
10116 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10117 sRef_setKept (os, loc);
10122 if (uentry_incompatibleMemoryStates (os, rs))
10124 if (uentry_relevantReference (rs, !flip))
10126 if (sRef_isLocalParamVar (rs)
10127 && (sRef_isDependent (rs)
10128 || sRef_isLocalState (rs)))
10130 if (sRef_isDependent (os))
10132 sRef_setDependent (rs, loc);
10136 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10141 if (sRef_isParam (os))
10144 ** If the local variable associated
10145 ** with the param has the correct state,
10147 ** (e.g., free (s); s = new(); ...
10150 uentry uvar = usymtab_lookupSafe (other->uname);
10152 if (uentry_isValid (uvar)
10153 && ((sRef_isDead (os)
10154 && sRef_isOnly (uvar->sref))
10155 || (sRef_isDependent (os)
10156 && sRef_isOwned (uvar->sref))))
10162 branchStateAltError (res, other,
10168 DPRINTF (("Here: %s / %s",
10169 uentry_unparseFull (res),
10170 uentry_unparseFull (other)));
10172 branchStateAltError (res, other,
10179 if (sRef_isKept (os))
10181 sRef_setKept (rs, loc);
10187 DPRINTF (("Merge opt..."));
10188 sRef_mergeOptState (rs, os, cl, loc);
10189 DPRINTF (("Done!"));
10193 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10194 sRef_mergeState (rs, os, cl, loc);
10195 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10200 if (sRef_isModified (os))
10202 sRef_setModified (rs);
10207 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10211 uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10213 valueTable rvalues;
10214 valueTable ovalues;
10216 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10224 rvalues = sRef_getValueTable (res->sref);
10225 ovalues = sRef_getValueTable (other->sref);
10227 if (valueTable_isUndefined (ovalues))
10229 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10232 else if (valueTable_isUndefined (rvalues))
10235 ** Copy values from other
10239 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10240 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10245 valueTable_elements (ovalues, fkey, fval) {
10247 metaStateInfo minfo;
10248 stateCombinationTable sctable;
10252 tval = valueTable_lookup (rvalues, fkey);
10254 DPRINTF (("Merge value: %s / %s X %s", fkey,
10255 stateValue_unparse (fval), stateValue_unparse (tval)));
10257 minfo = context_lookupMetaStateInfo (fkey);
10258 llassert (stateValue_isDefined (tval));
10260 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10262 DPRINTF (("Cannot find meta state for: %s", fkey));
10267 llassert (metaStateInfo_isDefined (minfo));
10269 if (stateValue_isError (fval)
10270 || sRef_definitelyNullContext (res->sref))
10272 sRef_setMetaStateValueComplete (res->sref,
10273 fkey, stateValue_getValue (fval),
10274 stateValue_getLoc (fval));
10275 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10277 else if (stateValue_isError (tval)
10278 || sRef_definitelyNullAltContext (other->sref))
10280 DPRINTF (("Other branch is definitely null!"));
10282 else if (sRef_isStateUndefined (res->sref)
10283 || sRef_isDead (res->sref))
10285 ; /* Combination state doesn't matter if it is undefined or dead */
10289 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10290 metaStateInfo_unparse (minfo),
10291 stateValue_unparse (fval),
10292 stateValue_unparse (tval)));
10294 DPRINTF (("state values: %d / %d",
10295 stateValue_getValue (fval), stateValue_getValue (tval)));
10297 sctable = metaStateInfo_getMergeTable (minfo);
10299 DPRINTF (("Merge table: %s",
10300 stateCombinationTable_unparse (sctable)));
10302 msg = cstring_undefined;
10304 nval = stateCombinationTable_lookup (sctable,
10305 stateValue_getValue (fval),
10306 stateValue_getValue (tval),
10309 DPRINTF (("nval: %d / %d / %d", nval,
10310 stateValue_getValue (fval), stateValue_getValue (tval)));
10312 if (nval == stateValue_error)
10314 /*@i32 print extra info for assignments@*/
10316 if (uentry_isGlobalMarker (res))
10321 ("Control branches merge with incompatible global states (%s and %s)%q",
10322 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10323 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10324 cstring_isDefined (msg)
10325 ? message (": %s", msg) : cstring_undefined),
10328 sRef_showMetaStateInfo (res->sref, fkey);
10329 sRef_showMetaStateInfo (other->sref, fkey);
10337 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10338 uentry_getName (res),
10339 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10340 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10341 cstring_isDefined (msg)
10342 ? message (": %s", msg) : cstring_undefined),
10345 sRef_showMetaStateInfo (res->sref, fkey);
10346 sRef_showMetaStateInfo (other->sref, fkey);
10347 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10348 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10349 DPRINTF (("Null: %s / %s",
10350 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10351 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10357 if (nval == stateValue_getValue (fval)
10358 && nval != stateValue_getValue (tval))
10360 loc = stateValue_getLoc (fval);
10362 else if (nval == stateValue_getValue (tval)
10363 && nval != stateValue_getValue (fval))
10365 loc = stateValue_getLoc (tval);
10372 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10373 && nval == stateValue_getValue (fval)
10374 && nval == stateValue_getValue (tval))
10380 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10384 } end_valueTable_elements ;
10390 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10391 bool flip, clause cl)
10393 if (cl == DOWHILECLAUSE)
10395 res->used = other->used || res->used;
10396 res->lset = other->lset || res->lset;
10397 res->uses = filelocList_append (res->uses, other->uses);
10398 other->uses = filelocList_undefined;
10402 if (sRef_isMacroParamRef (res->sref)
10403 && !uentry_isSefParam (other)
10404 && !uentry_isSefParam (res))
10406 bool hasError = FALSE;
10408 if (bool_equal (res->used, other->used))
10410 res->used = other->used;
10414 if (other->used && !flip)
10419 message ("Macro parameter %q used in true clause, "
10420 "but not in false clause",
10421 uentry_getName (res)),
10422 uentry_whereDeclared (res));
10429 message ("Macro parameter %q used in false clause, "
10430 "but not in true clause",
10431 uentry_getName (res)),
10432 uentry_whereDeclared (res));
10438 /* make it sef now, prevent more errors */
10439 res->info->var->kind = VKREFSEFPARAM;
10445 res->used = other->used || res->used;
10446 res->lset = other->lset || res->lset;
10447 res->uses = filelocList_append (res->uses, other->uses);
10448 other->uses = filelocList_undefined;
10454 uentry_mergeState (uentry res, uentry other, fileloc loc,
10455 bool mustReturn, bool flip, bool opt,
10458 llassert (uentry_isValid (res));
10459 llassert (uentry_isValid (other));
10461 llassert (res->ukind == other->ukind);
10462 llassert (res->ukind == KVAR);
10464 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10465 uentry_unparseFull (other)));
10467 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10468 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10469 uentry_mergeSetStates (res, other, loc, flip, cl);
10472 void uentry_setUsed (uentry e, fileloc loc)
10474 static bool firstTime = TRUE;
10475 static bool showUses = FALSE;
10476 static bool exportLocal = FALSE;
10478 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10482 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10484 showUses = context_getFlag (FLG_SHOWUSES);
10485 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10490 if (uentry_isValid (e))
10494 if (warnClause_isDefined (e->warn))
10496 flagSpec flg = warnClause_getFlag (e->warn);
10499 if (warnClause_hasMessage (e->warn))
10501 msg = cstring_copy (warnClause_getMessage (e->warn));
10505 msg = message ("Use of possibly dangerous %s",
10506 uentry_ekindNameLC (e));
10510 message ("%q: %q", msg, uentry_getName (e)),
10514 if (sRef_isMacroParamRef (e->sref))
10516 if (uentry_isYield (e) || uentry_isSefParam (e))
10522 if (context_inConditional ())
10526 message ("Macro parameter %q used in conditionally "
10527 "executed code (may or may not be "
10528 "evaluated exactly once)",
10529 uentry_getName (e)),
10532 e->info->var->kind = VKREFSEFPARAM;
10541 message ("Macro parameter %q used more than once",
10542 uentry_getName (e)),
10543 uentry_whereDeclared (e)))
10545 e->info->var->kind = VKREFSEFPARAM;
10552 if ((dp = uentry_directParamNo (e)) >= 0)
10554 uentry_setUsed (usymtab_getParam (dp), loc);
10559 if (!sRef_isLocalVar (e->sref))
10563 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10569 if (context_inMacro ())
10571 e->uses = filelocList_addUndefined (e->uses);
10575 e->uses = filelocList_addDifferentFile
10577 uentry_whereDeclared (e),
10586 bool uentry_isReturned (uentry u)
10588 return (uentry_isValid (u) && uentry_isVar (u)
10589 && (u->info->var->kind == VKRETPARAM
10590 || u->info->var->kind == VKSEFRETPARAM));
10593 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10595 llassert (uentry_isRealFunction (u));
10597 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10599 stateClauseList clauses = uentry_getStateClauseList (u);
10600 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10602 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10603 sRef_setAllocated (res, g_currentloc);
10605 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10606 stateClauseList_unparse (clauses)));
10609 ** This should be in exprNode_reflectEnsuresClause
10612 stateClauseList_postElements (clauses, cl)
10614 if (!stateClause_isGlobal (cl))
10616 sRefSet refs = stateClause_getRefs (cl);
10617 sRefMod modf = stateClause_getEffectFunction (cl);
10619 sRefSet_elements (refs, el)
10621 sRef base = sRef_getRootBase (el);
10623 if (sRef_isResult (base))
10627 sRef sr = sRef_fixBase (el, res);
10628 modf (sr, g_currentloc);
10635 } end_sRefSet_elements ;
10637 } end_stateClauseList_postElements ;
10645 sRefSet prefs = sRefSet_new ();
10646 sRef res = sRef_undefined;
10649 params = uentry_getParams (u);
10651 uentryList_elements (params, current)
10653 if (uentry_isReturned (current))
10655 if (exprNodeList_size (args) >= paramno)
10657 exprNode ecur = exprNodeList_nth (args, paramno);
10658 sRef tref = exprNode_getSref (ecur);
10660 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10662 if (sRef_isValid (tref))
10664 sRef tcref = sRef_copy (tref);
10666 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10668 if (sRef_isDead (tcref))
10670 sRef_setDefined (tcref, g_currentloc);
10671 sRef_setOnly (tcref, g_currentloc);
10674 if (sRef_isRefCounted (tcref))
10676 /* could be a new ref now (but only if its returned) */
10677 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10680 sRef_makeSafe (tcref);
10681 prefs = sRefSet_insert (prefs, tcref);
10687 } end_uentryList_elements ;
10689 if (sRefSet_size (prefs) > 0)
10691 nstate n = sRef_getNullState (u->sref);
10693 if (sRefSet_size (prefs) == 1)
10695 res = sRefSet_choose (prefs);
10699 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10700 res = sRefSet_mergeIntoOne (prefs);
10703 if (nstate_isKnown (n))
10705 sRef_setNullState (res, n, g_currentloc);
10710 if (ctype_isFunction (u->utype))
10712 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10713 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10717 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10720 if (sRef_isRefCounted (res))
10722 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10727 if (sRef_getNullState (res) == NS_ABSNULL)
10729 ctype ct = ctype_realType (u->utype);
10731 if (ctype_isAbstract (ct))
10733 sRef_setNotNull (res, g_currentloc);
10737 if (ctype_isUser (ct))
10739 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10743 sRef_setNotNull (res, g_currentloc);
10748 if (sRef_isRefCounted (res))
10750 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10752 else if (sRef_isKillRef (res))
10754 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10761 ak = sRef_getAliasKind (res);
10763 if (alkind_isImplicit (ak))
10765 sRef_setAliasKind (res,
10766 alkind_fixImplicit (ak),
10770 sRefSet_free (prefs);
10772 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10777 static bool uentry_isRefCounted (uentry ue)
10779 ctype ct = uentry_getType (ue);
10781 if (ctype_isFunction (ct))
10783 return (ctype_isRefCounted (ctype_getReturnType (ct)));
10787 return (ctype_isRefCounted (ct));
10792 ** old was declared yield in the specification.
10793 ** new is declared in the iter implementation.
10796 void uentry_checkYieldParam (uentry old, uentry unew)
10800 llassert (uentry_isVariable (old));
10801 llassert (uentry_isVariable (unew));
10803 unew->info->var->kind = VKYIELDPARAM;
10804 (void) checkTypeConformance (old, unew, TRUE);
10805 checkVarConformance (old, unew, TRUE, FALSE);
10807 /* get rid of param marker */
10809 name = uentry_getName (unew);
10810 cstring_free (unew->uname);
10811 unew->uname = name;
10812 unew->info->var->kind = VKREFYIELDPARAM;
10814 uentry_setUsed (old, fileloc_undefined);
10815 uentry_setUsed (unew, fileloc_undefined);
10818 /*@observer@*/ cstring
10819 uentry_ekindName (uentry ue)
10821 if (uentry_isValid (ue))
10826 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10828 return cstring_makeLiteralTemp ("Datatype");
10830 return cstring_makeLiteralTemp ("Enum member");
10832 return cstring_makeLiteralTemp ("Constant");
10834 if (uentry_isParam (ue))
10836 return cstring_makeLiteralTemp ("Parameter");
10838 else if (uentry_isExpandedMacro (ue))
10840 return cstring_makeLiteralTemp ("Expanded macro");
10844 return cstring_makeLiteralTemp ("Variable");
10847 return cstring_makeLiteralTemp ("Function");
10849 return cstring_makeLiteralTemp ("Iterator");
10851 return cstring_makeLiteralTemp ("Iterator finalizer");
10853 return cstring_makeLiteralTemp ("Struct tag");
10855 return cstring_makeLiteralTemp ("Union tag");
10857 return cstring_makeLiteralTemp ("Enum tag");
10859 return cstring_makeLiteralTemp ("Optional parameters");
10864 return cstring_makeLiteralTemp ("<Undefined>");
10870 /*@observer@*/ cstring
10871 uentry_ekindNameLC (uentry ue)
10873 if (uentry_isValid (ue))
10878 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10880 return cstring_makeLiteralTemp ("datatype");
10882 return cstring_makeLiteralTemp ("enum member");
10884 return cstring_makeLiteralTemp ("constant");
10886 if (uentry_isParam (ue))
10888 return cstring_makeLiteralTemp ("parameter");
10890 else if (uentry_isExpandedMacro (ue))
10892 return cstring_makeLiteralTemp ("expanded macro");
10896 return cstring_makeLiteralTemp ("variable");
10899 return cstring_makeLiteralTemp ("function");
10901 return cstring_makeLiteralTemp ("iterator");
10903 return cstring_makeLiteralTemp ("iterator finalizer");
10905 return cstring_makeLiteralTemp ("struct tag");
10907 return cstring_makeLiteralTemp ("union tag");
10909 return cstring_makeLiteralTemp ("enum tag");
10911 return cstring_makeLiteralTemp ("optional parameters");
10916 return cstring_makeLiteralTemp ("<Undefined>");
10922 void uentry_setHasNameError (uentry ue)
10924 llassert (uentry_isValid (ue));
10926 ue->hasNameError = TRUE;
10929 void uentry_checkName (uentry ue)
10931 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10932 uentry_observeRealName (ue),
10933 bool_unparse (uentry_isVisibleExternally (ue))));
10935 if (uentry_isValid (ue)
10936 && !context_inXHFile ()
10937 && uentry_hasName (ue)
10938 && !uentry_isElipsisMarker (ue)
10939 && context_getFlag (FLG_NAMECHECKS)
10940 && !ue->hasNameError
10941 && !uentry_isEndIter (ue)
10942 && !fileloc_isBuiltin (uentry_whereLast (ue))
10943 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10945 DPRINTF (("Here..."));
10947 if (uentry_isPriv (ue))
10949 ; /* any checks here? */
10951 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10953 ; /* no errors for externals */
10959 if (uentry_isExpandedMacro (ue))
10965 if (uentry_isExpandedMacro (ue))
10969 else if (uentry_isVariable (ue))
10971 sRef sr = uentry_getSref (ue);
10973 if (sRef_isValid (sr))
10975 scope = sRef_getScope (sr);
10982 else if (uentry_isFunction (ue)
10983 || uentry_isIter (ue)
10984 || uentry_isEndIter (ue)
10985 || uentry_isConstant (ue))
10987 scope = uentry_isStatic (ue) ? fileScope : globScope;
10989 else /* datatypes, etc. must be global */
10994 usymtab_checkDistinctName (ue, scope);
10997 if (context_getFlag (FLG_CPPNAMES))
11002 if (scope == globScope)
11004 checkExternalName (ue);
11006 else if (scope == fileScope)
11008 checkFileScopeName (ue);
11012 checkLocalName (ue);
11016 checkAnsiName (ue);
11021 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11027 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11030 if (!context_inMacro ())
11032 sRef_setGlobalScopeSafe ();
11035 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11036 uentry_setUsed (ue, loc);
11038 tloc = fileloc_createExternal ();
11039 uentry_setDefined (ue, tloc);
11040 fileloc_free (tloc);
11041 uentry_setHasNameError (ue);
11043 if (context_getFlag (FLG_REPEATUNRECOG))
11045 uentry_markOwned (ue);
11049 ue = usymtab_supReturnFileEntry (ue);
11052 if (!context_inMacro ())
11054 sRef_clearGlobalScopeSafe ();
11060 uentry uentry_makeGlobalMarker ()
11065 llassert (sRef_inGlobalScope ());
11067 ue = uentry_makeVariableAux
11068 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11069 sRef_makeGlobalMarker (),
11072 tloc = fileloc_createExternal ();
11073 uentry_setUsed (ue, tloc);
11074 uentry_setDefined (ue, tloc);
11075 fileloc_free (tloc);
11076 uentry_setHasNameError (ue);
11082 bool uentry_isGlobalMarker (uentry ue)
11084 return (uentry_isValid (ue)
11085 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11088 /* new start modifications */
11090 /* start modifications */
11092 requires: p_e is defined, is a ptr/array variable
11094 effects: sets the state of the variable
11098 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
11099 /*@access sRef@*/ /*i523 shouldn't do this! */
11100 if( uentry_isValid(p_e) ) {
11101 if( p_e->info != NULL) {
11102 if( p_e->info->var != NULL) {
11103 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11104 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11109 /*@noaccess sRef@*/
11111 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11115 requires: p_e is defined, is a ptr/array variable
11117 effects: sets the size of the buffer
11120 void uentry_setNullTerminatedState (uentry p_e) {
11121 if( uentry_isValid(p_e) ) {
11122 if( p_e->info != NULL) {
11123 if( p_e->info->var != NULL) {
11124 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11125 /*@access sRef@*/ /*@i523 bad!*/
11126 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11127 /*@noaccess sRef@*/
11133 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11137 requires: p_e is defined, is a ptr/array variable
11139 effects: sets the size of the buffer
11142 void uentry_setSize (uentry p_e, int size) {
11143 if( uentry_isValid(p_e) ) {
11144 if( p_e->info != NULL) {
11145 if( p_e->info->var != NULL) {
11146 p_e->info->var->bufinfo->size = size;
11147 /*@access sRef@*/ /*@i523 bad!*/
11148 p_e->sref->bufinfo.size = size;
11149 /*@noaccess sRef@*/
11155 fprintf(stderr, "uentry:Error in setSize\n");
11160 requires: p_e is defined, is a ptr/array variable
11162 effects: sets the length of the buffer
11165 void uentry_setLen (uentry p_e, int len) {
11166 if( uentry_isValid(p_e) ) {
11167 if( p_e->info != NULL) {
11168 if( p_e->info->var != NULL) {
11169 p_e->info->var->bufinfo->len = len;
11170 /*@access sRef@*/ /*@i523 bad!*/
11171 p_e->sref->bufinfo.len = len;
11172 /*@noaccess sRef@*/
11178 fprintf(stderr, "uentry:Error in setLen\n");
11183 bool uentry_hasMetaStateEnsures (uentry e)
11185 if (uentry_isValid (e) && uentry_isFunction (e))
11187 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11195 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11197 llassert (uentry_isValid (e) && uentry_isFunction (e));
11198 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);