2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 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 splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 # include "splintMacros.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 /*@only@*/ /*@notnull@*/ uentry
96 uentry_makeConstantAux (cstring p_n, ctype p_t,
97 /*@keep@*/ fileloc p_f, bool p_priv, bool p_macro,
98 /*@only@*/ multiVal p_m) /*@*/ ;
100 static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
102 if (uentry_isVariable (ue)
103 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
104 || ctype_isUnknown (uentry_getType (ue))))
106 uentry_makeVarFunction (ue);
110 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
112 uentry ue = (uentry) dmalloc (sizeof (*ue));
113 ue->warn = warnClause_undefined; /*@i32@*/
120 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
121 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
123 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
124 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
125 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
126 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
127 static void ucinfo_free (/*@only@*/ ucinfo p_u);
128 static void uvinfo_free (/*@only@*/ uvinfo p_u);
132 static /*@only@*/ cstring ancontext_unparse (ancontext an)
136 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
137 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
138 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
139 case AN_SUFIELD: return cstring_makeLiteral ("su field");
140 case AN_TDEFN: return cstring_makeLiteral ("type definition");
141 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
142 case AN_CONST: return cstring_makeLiteral ("constant");
148 static int annots[AN_LAST][QU_LAST];
149 static int decls[AN_LAST];
150 static int shdecls[AN_LAST];
151 static int idecls[AN_LAST];
157 for (i = AN_UNKNOWN; i < AN_LAST; i++)
163 for (j = QU_UNKNOWN; j < QU_LAST; j++)
170 static void tallyAnnot (ancontext ac, qual q)
184 for (j = QU_UNKNOWN; j < QU_LAST; j++)
189 for (i = AN_UNKNOWN; i < AN_LAST; i++)
195 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
196 ancontext_unparse (i),
197 decls[i], shdecls[i], idecls[i]);
199 totdecls += decls[i];
200 totshdecls += shdecls[i];
201 totidecls += idecls[i];
203 for (j = QU_UNKNOWN; j < QU_LAST; j++)
205 total[j] += annots[i][j];
206 alltotals += annots[i][j];
209 printf (" Allocation:\n");
213 for (j = QU_UNKNOWN; j < QU_LAST; j++)
215 if (qual_isAliasQual (j) && !qual_isUnique (j))
217 if (annots[i][j] > 0)
219 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
220 100.0 * (double)annots[i][j] / (double)decls[i]);
221 tmptot += annots[i][j];
226 printf (" Exposure:\n");
230 for (j = QU_UNKNOWN; j < QU_LAST; j++)
232 if (qual_isExQual (j))
234 if (annots[i][j] > 0)
236 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
237 100.0 * (double)annots[i][j] / (double)decls[i]);
238 tmptot += annots[i][j];
243 printf (" Definition:\n");
245 for (j = QU_UNKNOWN; j < QU_LAST; j++)
247 if (qual_isAllocQual (j))
249 if (annots[i][j] > 0)
251 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
252 100.0 * (double)annots[i][j] / (double)decls[i]);
259 for (j = QU_UNKNOWN; j < QU_LAST; j++)
261 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
263 if (annots[i][j] > 0)
265 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
266 100.0 * (double)annots[i][j] / (double)decls[i]);
275 for (j = QU_UNKNOWN; j < QU_LAST; j++)
279 for (i = AN_UNKNOWN; i < AN_LAST; i++)
281 if (annots[i][j] > 0)
290 printf ("Annotation: %s\n", qual_unparse (j));
292 for (i = AN_UNKNOWN; i < AN_LAST; i++)
294 if (annots[i][j] > 0)
296 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
303 printf ("All Contexts\n");
305 for (j = QU_UNKNOWN; j < QU_LAST; j++)
309 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
310 100.0 * (double)total[j] / (double)(totdecls));
315 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
317 extern void uentry_tallyAnnots (uentry u, ancontext kind)
319 alkind ak = sRef_getAliasKind (u->sref);
320 exkind ek = sRef_getExKind (u->sref);
321 nstate ns = sRef_getNullState (u->sref);
322 sstate ss = sRef_getDefState (u->sref);
323 bool recordUnknown = FALSE;
325 if (kind == AN_UNKNOWN)
333 else if (e == KCONST || e == KENUMCONST)
337 else if (e == KFCN || e == KITER)
339 uentryList params = uentry_getParams (u);
342 uentryList_elements (params, current)
344 if (uentry_isReturned (current))
348 if (!uentry_isElipsisMarker (current))
350 uentry_tallyAnnots (current, AN_FCNPARAM);
352 } end_uentryList_elements;
356 if (ctype_isFunction (u->utype)
358 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
360 recordUnknown = TRUE;
363 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
365 ctype t = ctype_realType (u->utype);
369 uentryList fields = ctype_getFields (t);
371 uentryList_elements (fields, current)
373 uentry_tallyAnnots (current, AN_SUFIELD);
375 } end_uentryList_elements;
379 if (ctype_isVisiblySharable (u->utype))
381 recordUnknown = TRUE;
389 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
391 recordUnknown = TRUE;
398 if (kind == AN_FCNRETURN)
412 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
417 if (ctype_isRealPointer (ctype_realType (u->utype)))
425 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
426 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
427 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
428 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
432 if (uentry_isReturned (u))
434 tallyAnnot (kind, QU_RETURNED);
440 if (ctype_isRefCounted (ctype_realType (u->utype))
441 || (ctype_isFunction (u->utype) &&
442 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
448 if (kind == AN_FCNPARAM)
450 tallyAnnot (kind, QU_TEMP);
452 else if (recordUnknown)
454 if (kind == AN_FCNRETURN)
457 tallyAnnot (kind, QU_UNKNOWN);
461 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
462 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
463 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
464 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
466 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
467 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
468 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
469 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
470 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
471 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
472 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
473 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
474 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
475 case AK_IMPDEPENDENT:
476 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
486 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
487 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
493 case NS_ERROR: break;
494 case NS_UNKNOWN: break;
495 case NS_NOTNULL: break;
496 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
497 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
498 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
499 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
501 case NS_ABSNULL: break;
507 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
511 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
512 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
513 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
514 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
515 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
521 static specCode specCode_fromInt (int i)
524 llassert (i >= SPC_NONE && i < SPC_LAST);
526 return ((specCode) i);
530 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
532 if (uentry_isDeclared (u))
534 return cstring_makeLiteralTemp ("previously declared");
538 return cstring_makeLiteralTemp ("specified");
542 /*@observer@*/ cstring uentry_specDeclName (uentry u)
544 if (uentry_isDeclared (u))
546 return cstring_makeLiteralTemp ("previous declaration");
550 return cstring_makeLiteralTemp ("specification");
554 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
556 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
558 return cstring_makeLiteralTemp ("redefined");
560 else if (uentry_isCodeDefined (unew))
562 return cstring_makeLiteralTemp ("defined");
564 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
566 return cstring_makeLiteralTemp ("redeclared");
570 return cstring_makeLiteralTemp ("declared");
574 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
576 if (uentry_isValid (ue))
578 functionConstraint constraint;
580 DPRINTF((message ("called uentry_getFcnPostconditions on %s",
581 uentry_unparse (ue) ) ) );
583 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
585 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
586 uentry_unparse (ue) ) ) );
587 if (!uentry_isFunction (ue) )
589 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
590 uentry_unparse (ue) ) ));
591 return constraintList_undefined;
595 return constraintList_undefined;
598 if (!uentry_isFunction(ue))
601 DPRINTF((message ("called uentry_getFunctionConditions on non function %s",
602 uentry_unparse (ue) ) ) );
603 return constraintList_undefined;
607 llassert (uentry_isFunction (ue));
611 constraint = ue->info->fcn->postconditions;
615 constraint = ue->info->fcn->preconditions;
618 return functionConstraint_getBufferConstraints (constraint);
621 return constraintList_undefined;
626 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
628 return uentry_getFunctionConditions (ue, FALSE);
635 constraintList uentry_getFcnPostconditions (uentry ue)
637 return uentry_getFunctionConditions (ue, TRUE);
640 static /*@only@*/ fileloc setLocation (void)
642 fileloc fl = context_getSaveLocation ();
644 if (fileloc_isDefined (fl))
650 return fileloc_copy (g_currentloc);
654 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
656 llassert (uentry_isEitherConstant (ue));
657 sRef_setValue (ue->sref, val);
660 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
662 fileloc loc = setLocation ();
663 uentry ue = uentry_makeConstant (n, t, loc);
665 ue->ukind = KENUMCONST;
666 uentry_setDefined (ue, loc);
670 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
672 fileloc loc = setLocation ();
673 uentry ue = uentry_makeConstant (n, t, loc);
674 ctype etype = exprNode_getType (expr);
676 if (!ctype_isRealInt (etype)) {
680 ("Value of enum member is not an integeral type (type %s): %s",
681 ctype_unparse (etype), exprNode_unparse (expr)),
682 exprNode_loc (expr));
685 ue->ukind = KENUMCONST;
686 uentry_setDefined (ue, loc);
691 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
693 uentry ue = uentry_makeConstant (n, t, loc);
695 ue->ukind = KENUMCONST;
700 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
702 return uentry_makeVariable (n, t, setLocation (), FALSE);
706 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
708 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
712 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
714 ctype ct = idDecl_getCtype (id);
715 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
716 MAYBE, MAYBE, setLocation ());
718 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
720 if (!ynm_isOn (ue->info->datatype->abs))
722 if (ctype_isUnknown (ct))
724 ue->info->datatype->mut = MAYBE;
728 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
735 void uentry_checkParams (uentry ue)
737 if (uentry_isValid (ue))
739 bool isExt = uentry_isExtern (ue);
741 if (uentry_isRealFunction (ue))
743 uentryList params = uentry_getParams (ue);
745 uentryList_elements (params, current)
747 if (uentry_isValid (current))
749 ctype ct = current->utype;
751 if (ctype_isFixedArray (ct))
753 if (ctype_isArray (ctype_baseArrayPtr (ct))
754 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
761 (FLG_FIXEDFORMALARRAY,
762 message ("Function parameter %q declared as "
763 "manifest array (size constant is meaningless)",
764 uentry_getName (current)),
765 uentry_whereDeclared (current));
770 if (ctype_isArray (ct))
774 message ("Function parameter %q declared as "
775 "array (treated as pointer)",
776 uentry_getName (current)),
777 uentry_whereDeclared (current));
781 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
783 if (ctype_isAbstract (ct) &&
784 (isExt || (ctype_isAbstract (ctype_realType (ct))
785 && !context_hasFileAccess (ctype_typeId (ct)))))
790 ("Function %q declared with notnull parameter %q of abstract "
793 uentry_getName (current),
796 ("Since %s is an abstract type, notnull can only be "
797 "used for parameters if the function is static to a "
798 "module where %s is accessible.",
801 uentry_whereDeclared (current));
805 } end_uentryList_elements;
807 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
809 ctype ct = ue->utype;
811 if (ctype_isAbstract (ct)
812 && (isExt || (ctype_isAbstract (ctype_realType (ct))
813 && !context_hasFileAccess (ctype_typeId (ct)))))
818 ("%s %q declared %s notnull storage of abstract type %s",
819 ekind_capName (uentry_getKind (ue)),
824 ("Since %s is an abstract type, notnull can only be used "
825 "if it is static to a module where %s is accessible.",
828 uentry_whereDeclared (ue));
835 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
837 alkind ak = sRef_getAliasKind (ue->sref);
839 if (alkind_isRefCounted (ak))
841 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
845 if (alkind_isUnknown (ak))
847 exkind ek = sRef_getExKind (ue->sref);
849 if (exkind_isKnown (ek))
851 DPRINTF (("Setting imp dependent: %s",
852 uentry_unparseFull (ue)));
853 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
857 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
859 /* evans 2000-12-22 removed ctype_realType so it will
860 not apply to immutable abstract types. */
862 if (ctype_isVisiblySharable
863 (ctype_realType (ctype_getReturnType (ue->utype))))
865 if (uentryList_hasReturned (uentry_getParams (ue)))
871 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
873 ; /* Immutable objects are not shared. */
877 sRef_setAliasKind (ue->sref, AK_IMPONLY,
879 DPRINTF (("Ret imp only: %s",
880 ctype_unparse (ctype_getReturnType (ue->utype))));
890 static /*@notnull@*/ uentry
891 uentry_makeFunctionAux (cstring n, ctype t,
893 /*@only@*/ globSet globs,
894 /*@only@*/ sRefSet mods,
895 /*@only@*/ warnClause warn,
896 /*@keep@*/ fileloc f, bool priv,
897 /*@unused@*/ bool isForward)
899 uentry e = uentry_alloc ();
902 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
904 DPRINTF (("Make function: %s", n));
906 if (ctype_isFunction (t))
908 ret = ctype_getReturnType (t);
912 if (ctype_isKnown (t))
914 llbug (message ("not function: %s", ctype_unparse (t)));
921 if (fileloc_isSpec (f) || fileloc_isImport (f))
923 e->whereSpecified = f;
924 e->whereDeclared = fileloc_undefined;
928 e->whereSpecified = fileloc_undefined;
929 e->whereDeclared = f;
932 /* e->shallowCopy = FALSE; */
933 e->uname = cstring_copy (n);
935 e->storageclass = SCNONE;
937 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
939 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
941 if (ctype_isUA (ret))
943 sRef_setStateFromType (e->sref, ret);
948 e->uses = filelocList_new ();
950 e->hasNameError = FALSE;
954 e->info = (uinfo) dmalloc (sizeof (*e->info));
955 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
957 e->info->fcn->hasMods = sRefSet_isDefined (mods);
958 e->info->fcn->hasGlobs = globSet_isDefined (globs);
960 e->info->fcn->exitCode = XK_UNKNOWN;
961 e->info->fcn->nullPred = qual_createUnknown ();
962 e->info->fcn->specialCode = SPC_NONE;
964 e->info->fcn->access = access;
965 e->info->fcn->globs = globs;
966 e->info->fcn->defparams = uentryList_undefined;
968 sRef_setDefined (e->sref, f);
969 e->whereDefined = fileloc_undefined;
971 e->info->fcn->mods = sRefSet_undefined;
972 e->info->fcn->specclauses = NULL;
975 e->info->fcn->preconditions = NULL;
979 e->info->fcn->postconditions = NULL;
982 checkGlobalsModifies (e, mods);
983 e->info->fcn->mods = mods;
988 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
990 functionClauseList_elements (clauses, el)
992 DPRINTF (("Reflect clause: %s on %s",
993 functionClause_unparse (el), uentry_getName (ue)));
995 if (functionClause_isNoMods (el))
997 modifiesClause mel = functionClause_getModifies (el);
999 if (uentry_hasGlobs (ue))
1004 ("No globals and modifies inconsistent to globals clause for %q: %q",
1005 uentry_getName (ue),
1006 globSet_unparse (uentry_getGlobs (ue))),
1007 modifiesClause_getLoc (mel));
1011 if (uentry_hasMods (ue))
1016 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1017 uentry_getName (ue),
1018 sRefSet_unparse (uentry_getMods (ue))),
1019 modifiesClause_getLoc (mel));
1022 uentry_setGlobals (ue, globSet_undefined);
1023 uentry_setModifies (ue, sRefSet_undefined);
1025 else if (functionClause_isGlobals (el))
1027 globalsClause glc = functionClause_getGlobals (el);
1029 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1030 globalsClause_unparse (glc)));
1032 if (uentry_hasGlobs (ue))
1037 ("Multiple globals clauses for %q: %q",
1038 uentry_getName (ue),
1039 globalsClause_unparse (glc)),
1040 globalsClause_getLoc (glc));
1041 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1045 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1046 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1047 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1050 else if (functionClause_isModifies (el))
1052 modifiesClause mlc = functionClause_getModifies (el);
1054 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1056 if (uentry_hasMods (ue))
1064 ("Multiple modifies clauses for %s: %s",
1065 uentry_getName (ue),
1066 modifiesClause_unparse (mlc)),
1067 modifiesClause_getLoc (mlc)))
1069 llhint (message ("Previous modifies clause: ",
1070 sRefSet_unparse (uentry_getMods (ue))));
1076 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1080 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1083 else if (functionClause_isEnsures (el))
1085 functionConstraint cl = functionClause_takeEnsures (el);
1086 DPRINTF (("Setting post: %s / %s",
1087 uentry_unparse (ue), functionConstraint_unparse (cl)));
1088 uentry_setPostconditions (ue, cl);
1090 else if (functionClause_isRequires (el))
1092 functionConstraint cl = functionClause_takeRequires (el);
1093 uentry_setPreconditions (ue, cl);
1095 else if (functionClause_isState (el))
1097 stateClause sc = functionClause_takeState (el);
1099 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1101 sRefSet rfs = stateClause_getRefs (sc);
1103 sRefSet_elements (rfs, s)
1105 if (sRef_isParam (s))
1108 ** Can't use requires on parameters
1112 (FLG_ANNOTATIONERROR,
1113 message ("Requires clauses for %q concerns parameters %q should be "
1114 "a parameter annotation instead: %q",
1115 uentry_unparse (ue),
1117 stateClause_unparse (sc)),
1118 stateClause_loc (sc));
1120 } end_sRefSet_elements ;
1123 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1124 uentry_addStateClause (ue, sc);
1126 else if (functionClause_isWarn (el))
1128 warnClause wc = functionClause_takeWarn (el);
1129 uentry_addWarning (ue, wc);
1133 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1135 } end_functionClauseList_elements ;
1137 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1138 stateClauseList_checkAll (ue);
1141 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1143 bool leaveFunc = FALSE;
1145 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1146 typeId_invalid, globSet_undefined,
1147 sRefSet_undefined, warnClause_undefined,
1150 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1153 ** This makes parameters names print out correctly.
1154 ** (But we might be a local variable declaration for a function type...)
1157 if (context_inFunctionLike ())
1159 DPRINTF (("Header: %s / %s",
1160 uentry_unparse (context_getHeader ()),
1161 idDecl_unparse (id)));
1165 context_enterFunctionDeclaration (ue);
1169 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1170 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1171 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1172 reflectImplicitFunctionQualifiers (ue, FALSE);
1173 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1174 uentry_reflectClauses (ue, idDecl_getClauses (id));
1175 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1177 if (!uentry_isStatic (ue)
1178 && cstring_equalLit (ue->uname, "main"))
1180 ctype typ = ue->utype;
1184 llassert (ctype_isFunction (typ));
1186 retval = ctype_getReturnType (typ);
1188 if (!ctype_isInt (retval))
1192 message ("Function main declared to return %s, should return int",
1193 ctype_unparse (retval)),
1194 uentry_whereDeclared (ue));
1197 args = ctype_argsFunction (typ);
1199 if (uentryList_isMissingParams (args)
1200 || uentryList_size (args) == 0)
1206 if (uentryList_size (args) != 2)
1210 message ("Function main declared with %d arg%&, "
1211 "should have 2 (int argc, char *argv[])",
1212 uentryList_size (args)),
1213 uentry_whereLast (ue));
1217 uentry arg = uentryList_getN (args, 0);
1218 ctype ct = uentry_getType (arg);
1220 if (!ctype_isInt (ct))
1224 message ("Parameter 1, %q, of function main declared "
1225 "with type %t, should have type int",
1226 uentry_getName (arg), ct),
1227 uentry_whereDeclared (arg));
1230 arg = uentryList_getN (args, 1);
1231 ct = uentry_getType (arg);
1233 if (ctype_isArrayPtr (ct)
1234 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1235 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1243 message ("Parameter 2, %q, of function main declared "
1244 "with type %t, should have type char **",
1245 uentry_getName (arg), ct),
1246 uentry_whereDeclared (arg));
1254 context_exitFunctionDeclaration ();
1260 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1262 alkind ak = sRef_getAliasKind (e->sref);
1264 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1265 && context_getFlag (FLG_PARAMIMPTEMP))
1267 exkind ek = sRef_getExKind (e->sref);
1269 if (exkind_isKnown (ek))
1271 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1272 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1273 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1277 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1278 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1283 static /*@only@*/ /*@notnull@*/ uentry
1284 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1285 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1287 cstring pname = makeParam (n);
1290 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1291 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1293 cstring_free (pname);
1294 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1295 uentry_implicitParamAnnots (e);
1296 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1298 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1300 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1301 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1302 e->info->var->defstate = defstate;
1305 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1311 uentry_setRefCounted (uentry e)
1313 if (uentry_isValid (e))
1315 uentry_setAliasKind (e, AK_REFCOUNTED);
1316 sRef_storeState (e->sref);
1322 uentry_setStatic (uentry c)
1324 if (uentry_isValid (c))
1326 alkind ak = sRef_getAliasKind (c->sref);
1327 c->storageclass = SCSTATIC;
1329 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1331 if (!alkind_isUnknown (ak)
1332 && !alkind_isStatic (ak))
1334 if (!(ctype_isRealPointer (uentry_getType (c)))
1335 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1336 && !alkind_isRefCounted (ak))
1338 if (alkind_isImplicit (ak)
1339 && alkind_isDependent (ak)
1340 && ctype_isArray (uentry_getType (c)))
1342 ; /* no error for observer arrays */
1348 message ("Static storage %q declared as %s",
1350 alkind_unparse (ak)),
1351 uentry_whereDeclared (c));
1357 if (alkind_isUnknown (ak)
1358 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1359 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1361 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1362 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1370 uentry_setExtern (uentry c)
1372 if (uentry_isValid (c))
1373 c->storageclass = SCEXTERN;
1377 uentry_setParamNo (uentry ue, int pno)
1379 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1380 sRef_setParamNo (ue->sref, pno);
1384 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1386 sRefSet_allElements (sr, el)
1388 sRef base = sRef_getRootBase (el);
1390 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1391 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1393 if (!globSet_member (ue->info->fcn->globs, base))
1395 if (uentry_hasGlobs (ue)
1396 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1399 (FLG_WARNMISSINGGLOBALS,
1401 ("Modifies list for %q uses global %q, "
1402 "not included in globals list.",
1403 uentry_getName (ue),
1404 sRef_unparse (base)),
1405 uentry_whereLast (ue)))
1407 uentry_showWhereSpecified (ue);
1411 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1413 if (sRef_isFileStatic (base))
1415 context_recordFileGlobals (ue->info->fcn->globs);
1419 } end_sRefSet_allElements;
1423 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1425 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1429 uentry_fixupSref (uentry ue)
1433 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1438 sr = uentry_getSref (ue);
1440 sRef_resetState (sr);
1441 sRef_clearDerived (sr);
1443 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1444 llassert (sRef_isValid (sr));
1446 if (uentry_isVariable (ue))
1448 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1449 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1450 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1454 static void uentry_addStateClause (uentry ue, stateClause sc)
1457 ** Okay to allow multiple clauses of the same kind.
1458 */ /*@i834 is this true?@*/
1460 ue->info->fcn->specclauses =
1461 stateClauseList_add (ue->info->fcn->specclauses, sc);
1463 /* Will call checkAll to check later... */
1466 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1468 llassert (uentry_isFunction (ue));
1469 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1471 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1472 ue->info->fcn->specclauses = clauses;
1473 stateClauseList_checkAll (ue);
1474 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1478 ** Used for @modifies@ @endmodifies@ syntax.
1480 ** If ue is specified, sr must contain *only*:
1482 ** o file static globals
1483 ** o sRef's derived from modifies spec (i.e., more specific than
1484 ** what was specified)
1486 ** Otherwise, if sr has modifies it must match sr.
1488 ** If it doesn't have modifies, set them to sr.
1492 uentry_checkModifiesContext (void)
1494 if (sRef_modInFunction ())
1498 ("Modifies list not in function context. "
1499 "A modifies list can only appear following the parameter list "
1500 "in a function declaration or header."));
1509 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1511 if (!uentry_checkModifiesContext ())
1517 if (uentry_isValid (ue))
1519 if (uentry_isIter (ue))
1521 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1522 ue->info->iter->mods = sr;
1526 uentry_convertVarFunction (ue);
1527 llassertfatal (uentry_isFunction (ue));
1528 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1530 ue->info->fcn->mods = sr;
1531 ue->info->fcn->hasMods = TRUE;
1533 checkGlobalsModifies (ue, sr);
1536 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1538 ue->info->fcn->hasGlobs = TRUE;
1541 if (sRefSet_hasStatic (ue->info->fcn->mods))
1543 context_recordFileModifies (ue->info->fcn->mods);
1553 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1556 ** Function already has one modifies clause (possibly from
1557 ** a specification).
1560 if (!uentry_checkModifiesContext ())
1565 llassert (uentry_isValid (ue));
1567 if (uentry_isIter (ue))
1569 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1573 llassertfatal (uentry_isFunction (ue));
1574 llassert (ue->info->fcn->hasMods);
1576 checkGlobalsModifies (ue, sr);
1577 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1579 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1581 ue->info->fcn->hasGlobs = TRUE;
1585 if (sRefSet_hasStatic (ue->info->fcn->mods))
1587 context_recordFileModifies (ue->info->fcn->mods);
1591 bool uentry_hasWarning (uentry ue)
1593 return (uentry_isValid (ue)
1594 && warnClause_isDefined (ue->warn));
1597 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1599 llassert (warnClause_isUndefined (ue->warn));
1604 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1606 if (sRef_modInFunction ())
1609 (message ("Precondition list not in function context. "
1610 "A precondition list can only appear following the parameter list "
1611 "in a function declaration or header."));
1613 /*@-mustfree@*/ return; /*@=mustfree@*/
1616 if (uentry_isValid (ue))
1618 uentry_convertVarFunction (ue);
1619 llassertfatal (uentry_isFunction (ue));
1621 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1624 I changed this so it didn't appear as a Splint bug
1625 among other things this gets triggered when there is
1626 a function with two requires clauses. Now Splint
1627 prints an error and tries to conjoin the lists.
1630 (message ("Duplicate precondition list"
1631 "Attemping the conjoin the requires clauses"
1635 /* should conjoin constraints? */
1637 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1641 ue->info->fcn->preconditions = preconditions;
1646 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1655 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1657 if (sRef_modInFunction ())
1660 (message ("Postcondition list not in function context. "
1661 "A postcondition list can only appear following the parameter list "
1662 "in a function declaration or header."));
1664 /*@-mustfree@*/ return; /*@=mustfree@*/
1667 if (uentry_isValid (ue))
1669 uentry_convertVarFunction (ue);
1670 llassertfatal (uentry_isFunction (ue));
1672 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1674 ue->info->fcn->postconditions = postconditions;
1678 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1683 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1688 ** requires: new and old are functions
1692 checkGlobalsConformance (/*@notnull@*/ uentry old,
1693 /*@notnull@*/ uentry unew,
1694 bool mustConform, bool completeConform)
1696 bool hasInternalState = FALSE;
1698 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1700 if (globSet_isDefined (unew->info->fcn->globs))
1702 globSet_allElements (unew->info->fcn->globs, el)
1704 if (sRef_isFileStatic (el))
1706 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1708 if (sRef_isInvalid (sr))
1710 bool hasError = FALSE;
1712 if (!hasInternalState
1713 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1714 sRef_makeInternalState ()))
1715 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1716 sRef_makeSpecState ())))
1719 && !uentry_isStatic (old)
1722 message ("Globals list for %q includes internal state, %q, "
1723 "but %s without globals internalState.",
1724 uentry_getName (old),
1726 uentry_specOrDefName (old)),
1727 uentry_whereLast (unew)))
1729 uentry_showWhereSpecified (old);
1733 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1734 sRef_makeInternalState ());
1735 hasInternalState = TRUE;
1739 && fileloc_sameFile (uentry_whereDeclared (unew),
1740 uentry_whereDeclared (old)))
1745 message ("Function %q inconsistently %rdeclared (in "
1746 "same file) with file static global %q in "
1748 uentry_getName (unew),
1749 uentry_isDeclared (old),
1751 uentry_whereDeclared (unew)))
1753 uentry_showWhereSpecified (old);
1758 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1759 context_recordFileGlobals (old->info->fcn->globs);
1763 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1765 if (sRef_isInvalid (sr))
1770 message ("Function %q inconsistently %rdeclared with "
1771 "%q in globals list",
1772 uentry_getName (unew),
1773 uentry_isDeclared (old),
1775 uentry_whereDeclared (unew)))
1777 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1778 uentry_showWhereSpecified (old);
1783 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1789 ("Function %q global %q inconsistently "
1790 "%rdeclared as %qout global",
1791 uentry_getName (unew),
1793 uentry_isDeclared (old),
1794 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1795 uentry_whereDeclared (unew)))
1797 uentry_showWhereSpecified (old);
1802 } end_globSet_allElements ;
1804 if (completeConform)
1806 globSet_allElements (old->info->fcn->globs, el)
1808 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1810 if (sRef_isInvalid (sr))
1813 && uentry_isReallySpecified (old)
1816 message ("Function %q specified with %q in globals list, "
1817 "but declared without %q",
1818 uentry_getName (unew),
1821 uentry_whereDeclared (unew)))
1823 uentry_showWhereSpecified (old);
1826 } end_globSet_allElements;
1831 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1833 if (uentry_isReallySpecified (old)
1836 message ("%s %q specified with globals list, but "
1837 "declared with no globals",
1838 ekind_capName (unew->ukind),
1839 uentry_getName (unew)),
1840 uentry_whereDeclared (unew)))
1843 (message ("Specification globals: %q",
1844 globSet_unparse (old->info->fcn->globs)),
1845 uentry_whereSpecified (old));
1849 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1850 old->info->fcn->globs);
1855 ** new modifies list must be included by old modifies list.
1857 ** file static state may be added to new, if old has internal.
1861 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1862 bool mustConform, bool completeConform)
1865 bool changedMods = FALSE;
1866 bool modInternal = FALSE;
1868 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1870 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1871 newMods = unew->info->fcn->mods;
1873 if (sRefSet_isEmpty (newMods))
1875 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1876 && uentry_isReallySpecified (old))
1880 message ("%s %q specified with modifies clause, "
1881 "but declared with no modifies clause",
1882 ekind_capName (unew->ukind),
1883 uentry_getName (unew)),
1884 uentry_whereDeclared (unew)))
1886 llgenindentmsg (message ("Specification has modifies %q",
1887 sRefSet_unparse (old->info->fcn->mods)),
1888 uentry_whereSpecified (old));
1895 sRefSet_allElements (newMods, current)
1897 if (sRef_isValid (current))
1899 sRef rb = sRef_getRootBase (current);
1901 if (sRef_isFileStatic (rb))
1905 if (!sRefSet_isSameMember (old->info->fcn->mods,
1906 sRef_makeInternalState ())
1907 && !sRefSet_isSameMember (old->info->fcn->mods,
1908 sRef_makeSpecState ()))
1911 && !uentry_isStatic (old)
1915 ("Modifies list for %q includes internal state, "
1916 "but %s without modifies internal.",
1917 uentry_getName (old),
1918 uentry_specOrDefName (old)),
1919 uentry_whereLast (unew)))
1921 uentry_showWhereSpecified (old);
1924 old->info->fcn->mods =
1925 sRefSet_insert (old->info->fcn->mods,
1926 sRef_makeInternalState ());
1931 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1937 if (sRef_canModifyVal (current, old->info->fcn->mods))
1939 int size = sRefSet_size (old->info->fcn->mods);
1941 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1944 if (sRefSet_size (old->info->fcn->mods) != size)
1955 ("Modifies list for %q contains %q, not modifiable "
1957 uentry_getName (old),
1958 sRef_unparse (current),
1959 uentry_specDeclName (old)),
1960 uentry_whereLast (unew)))
1962 uentry_showWhereSpecified (old);
1967 } end_sRefSet_allElements;
1969 if (completeConform && uentry_isReallySpecified (old))
1971 sRefSet_allElements (old->info->fcn->mods, el)
1973 if (sRef_canModify (el, newMods))
1982 ("Specification modifies clause for %q contains %q, "
1983 "not included in declaration modifies clause",
1984 uentry_getName (old),
1986 uentry_whereLast (unew)))
1988 uentry_showWhereSpecified (old);
1991 } end_sRefSet_allElements ;
1995 ** Make sure file static elements will be removed.
2000 context_recordFileModifies (old->info->fcn->mods);
2005 uentry_checkMutableType (uentry ue)
2007 ctype ct = uentry_getType (ue);
2009 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2011 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2013 voptgenerror (FLG_MUTREP,
2014 message ("Mutable abstract type %q declared without pointer "
2015 "indirection: %t (violates assignment semantics)",
2016 uentry_getName (ue), ct),
2017 uentry_whereDeclared (ue));
2022 uentry_setMutable (uentry e)
2024 llassert (uentry_isDatatype (e));
2025 e->info->datatype->mut = YES;
2029 uentry_checkIterArgs (uentry ue)
2031 bool hasYield = FALSE;
2034 llassert (uentry_isIter (ue));
2036 args = uentry_getParams (ue);
2038 uentryList_elements (args, el)
2040 sstate ds = uentry_getDefState (el);
2042 if (uentry_isYield (el))
2047 if (sstate_isUnknown (ds))
2049 uentry_setDefState (el, SS_DEFINED);
2055 } end_uentryList_elements;
2059 voptgenerror (FLG_HASYIELD,
2060 message ("Iterator %q declared with no yield parameters",
2061 uentry_getName (ue)),
2062 uentry_whereDeclared (ue));
2067 chkind_fromQual (qual qel)
2069 if (qual_isChecked (qel))
2073 else if (qual_isCheckMod (qel))
2077 else if (qual_isCheckedStrict (qel))
2079 return CH_CHECKEDSTRICT;
2081 else if (qual_isUnchecked (qel))
2083 return CH_UNCHECKED;
2088 /*@notreached@*/ return CH_UNKNOWN;
2093 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2095 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2097 if (!uentry_isRefCounted (ue))
2100 (FLG_ANNOTATIONERROR,
2101 message ("Reference counting qualifier %s used on non-reference "
2102 "counted storage: %q",
2104 uentry_unparse (ue)),
2105 uentry_whereLast (ue));
2109 alkind ak = alkind_fromQual (qel);
2111 uentry_setAliasKind (ue, ak);
2114 else if (qual_isRefCounted (qel))
2116 ctype ct = ctype_realType (uentry_getType (ue));
2119 if (ctype_isPointer (ct)
2120 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2122 /* check there is a refs field */
2123 uentryList fields = ctype_getFields (rt);
2124 uentry refs = uentry_undefined;
2126 uentryList_elements (fields, field)
2128 if (uentry_isRefsField (field))
2130 if (uentry_isValid (refs))
2133 (FLG_ANNOTATIONERROR,
2134 message ("Reference counted structure type %s has "
2135 "multiple refs fields: %q and %q",
2137 uentry_getName (refs),
2138 uentry_getName (field)),
2139 uentry_whereLast (field));
2144 } end_uentryList_elements;
2146 if (uentry_isInvalid (refs))
2150 message ("Reference counted structure type %s has "
2152 ctype_unparse (ct)),
2154 ("To count reference, the structure must have a field named "
2155 "refs of type int."),
2158 else if (!ctype_isInt (uentry_getType (refs)))
2161 (FLG_ANNOTATIONERROR,
2162 message ("Reference counted structure type %s refs field has "
2163 "type %s (should be int)", ctype_unparse (ct),
2164 ctype_unparse (uentry_getType (refs))),
2165 uentry_whereLast (refs));
2169 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2170 uentry_whereDeclared (ue));
2175 if ((ctype_isPointer (ct)
2176 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2177 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2179 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2180 uentry_whereDeclared (ue));
2185 (FLG_ANNOTATIONERROR,
2186 message ("Non-pointer to structure type %s declared with "
2187 "refcounted qualifier",
2188 ctype_unparse (ct)),
2189 uentry_whereLast (ue));
2193 else if (qual_isRefs (qel))
2195 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2197 uentry_setAliasKind (ue, AK_REFS);
2202 (FLG_ANNOTATIONERROR,
2203 message ("Refs qualifier used on non-structure field: %q",
2204 uentry_unparse (ue)),
2205 uentry_whereLast (ue));
2208 else if (qual_isAliasQual (qel))
2210 alkind ak = alkind_fromQual (qel);
2212 alkind oldak = uentry_getAliasKind (ue);
2213 ctype ut = uentry_getType (ue);
2215 if (alkind_isImplicit (ak)
2216 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2218 /* ignore the implied qualifier */
2222 if (uentry_isEitherConstant (ue))
2225 (FLG_ANNOTATIONERROR,
2226 message ("Alias qualifier %s used on constant: %q",
2227 alkind_unparse (ak), uentry_unparse (ue)),
2228 uentry_whereLast (ue));
2233 if (ctype_isFunction (ut))
2235 ut = ctype_getReturnType (ut);
2238 if (!(ctype_isVisiblySharable (ut)
2239 || ctype_isRealArray (ut)
2240 || ctype_isRealSU (ut)))
2242 if (!qual_isImplied (qel))
2245 (FLG_ANNOTATIONERROR,
2246 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2247 alkind_unparse (ak), ut, uentry_getName (ue)),
2248 uentry_whereLast (ue));
2255 if (uentry_isRefCounted (ue))
2257 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2258 || qual_isExposed (qel)
2259 || qual_isObserver (qel)))
2261 if (!qual_isImplied (qel))
2264 (FLG_ANNOTATIONERROR,
2266 ("Alias qualifier %s used on reference counted storage: %q",
2267 alkind_unparse (ak),
2268 uentry_unparse (ue)),
2269 uentry_whereLast (ue));
2277 if (qual_isRefQual (qel))
2280 (FLG_ANNOTATIONERROR,
2281 message ("Qualifier %s used on non-reference counted storage: %q",
2282 alkind_unparse (ak), uentry_unparse (ue)),
2283 uentry_whereLast (ue));
2292 uentry_setAliasKind (ue, ak);
2295 else if (qual_isNull (qel))
2297 if (uentry_isConstant (ue))
2301 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2302 uentry_whereDeclared (ue));
2306 uentry_setNullState (ue, NS_POSNULL);
2309 else if (qual_isRelNull (qel))
2311 uentry_setNullState (ue, NS_RELNULL);
2313 else if (qual_isNotNull (qel))
2315 uentry_setNullState (ue, NS_MNOTNULL);
2317 else if (qual_isAbstract (qel)
2318 || qual_isConcrete (qel))
2320 if (!uentry_isDatatype (ue))
2323 (FLG_ANNOTATIONERROR,
2324 message ("Qualifier %s used with non-datatype",
2325 qual_unparse (qel)),
2326 uentry_whereLast (ue));
2330 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2333 else if (qual_isMutable (qel))
2335 if (!uentry_isDatatype (ue))
2338 (FLG_ANNOTATIONERROR,
2339 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2340 uentry_whereLast (ue));
2344 if (!ynm_isOn (ue->info->datatype->mut))
2346 uentry_checkMutableType (ue);
2349 ue->info->datatype->mut = YES;
2352 else if (qual_isImmutable (qel))
2354 if (!uentry_isDatatype (ue))
2356 voptgenerror (FLG_ANNOTATIONERROR,
2357 message ("Qualifier %s used with non-datatype",
2358 qual_unparse (qel)),
2359 uentry_whereLast (ue));
2363 ue->info->datatype->mut = NO;
2366 else if (qual_isNullPred (qel))
2368 uentry_convertVarFunction (ue);
2370 if (uentry_isFunction (ue))
2372 ctype typ = uentry_getType (ue);
2373 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2375 if (ctype_isRealBool (rtype))
2377 uentryList pl = ctype_argsFunction (typ);
2379 if (uentryList_size (pl) == 1)
2381 ue->info->fcn->nullPred = qel;
2385 voptgenerror (FLG_ANNOTATIONERROR,
2386 message ("Qualifier %s used with function having %d "
2387 "arguments (should have 1)",
2389 uentryList_size (pl)),
2390 uentry_whereLast (ue));
2395 voptgenerror (FLG_ANNOTATIONERROR,
2396 message ("Qualifier %s used with function returning %s "
2397 "(should return bool)",
2399 ctype_unparse (rtype)),
2400 uentry_whereLast (ue));
2405 voptgenerror (FLG_ANNOTATIONERROR,
2406 message ("Qualifier %s used with non-function",
2407 qual_unparse (qel)),
2408 uentry_whereLast (ue));
2411 else if (qual_isExitQual (qel))
2413 exitkind exk = exitkind_fromQual (qel);
2415 if (uentry_isFunction (ue))
2417 if (exitkind_isKnown (ue->info->fcn->exitCode))
2419 voptgenerror (FLG_ANNOTATIONERROR,
2420 message ("Multiple exit qualifiers used on function %q: %s, %s",
2421 uentry_getName (ue),
2422 exitkind_unparse (ue->info->fcn->exitCode),
2423 exitkind_unparse (exk)),
2424 uentry_whereLast (ue));
2427 ue->info->fcn->exitCode = exk;
2431 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2433 uentry_makeVarFunction (ue);
2434 ue->info->fcn->exitCode = exk;
2438 voptgenerror (FLG_ANNOTATIONERROR,
2439 message ("Exit qualifier %s used with non-function (type %s)",
2441 ctype_unparse (uentry_getType (ue))),
2442 uentry_whereLast (ue));
2446 else if (qual_isMetaState (qel))
2448 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2450 if (annotationInfo_matchesContext (ainfo, ue))
2452 DPRINTF (("Reflecting %s on %s",
2453 annotationInfo_unparse (ainfo),
2454 uentry_unparseFull (ue)));
2456 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2457 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2458 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2463 (FLG_ANNOTATIONERROR,
2464 message ("Attribute annotation %s used in inconsistent context: %q",
2466 uentry_unparse (ue)),
2467 uentry_whereLast (ue)))
2469 /*@i! annotationInfo_showContextError (ainfo, ue); */
2475 if (qual_isCQual (qel))
2481 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2487 uentry_reflectQualifiers (uentry ue, qualList q)
2489 llassert (uentry_isValid (ue));
2491 DPRINTF (("Reflect qualifiers: %s / %s",
2492 uentry_unparseFull (ue), qualList_unparse (q)));
2494 qualList_elements (q, qel)
2496 if (qual_isStatic (qel))
2498 uentry_setStatic (ue);
2500 else if (qual_isUnused (qel))
2502 uentry_setUsed (ue, fileloc_undefined);
2504 else if (qual_isExternal (qel))
2506 fileloc_free (ue->whereDefined);
2507 ue->whereDefined = fileloc_createExternal ();
2509 else if (qual_isSef (qel))
2511 if (uentry_isVariable (ue))
2513 vkind vk = ue->info->var->kind;
2515 llassert (vk != VKREFPARAM);
2517 if (vk == VKYIELDPARAM)
2520 (FLG_ANNOTATIONERROR,
2521 message ("Qualifier sef cannot be used with %s: %q",
2522 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2523 uentry_unparse (ue)),
2524 uentry_whereLast (ue));
2526 else if (vk == VKRETPARAM)
2528 ue->info->var->kind = VKSEFRETPARAM;
2532 ue->info->var->kind = VKSEFPARAM;
2538 (FLG_ANNOTATIONERROR,
2539 message ("Qualifier sef is meaningful only on parameters: %q",
2540 uentry_unparse (ue)),
2541 uentry_whereLast (ue));
2544 else if (qual_isExtern (qel))
2546 ue->storageclass = SCEXTERN;
2548 else if (qual_isGlobalQual (qel)) /* undef, killed */
2550 DPRINTF (("Reflecting qual: %s / %s",
2551 qual_unparse (qel), uentry_unparse (ue)));
2553 if (uentry_isVariable (ue))
2555 sstate oldstate = ue->info->var->defstate;
2556 sstate defstate = sstate_fromQual (qel);
2559 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2560 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2562 defstate = SS_UNDEFKILLED;
2569 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2570 ue->info->var->defstate = defstate;
2575 (FLG_ANNOTATIONERROR,
2576 message ("Qualifier %s used on non-variable: %q",
2577 qual_unparse (qel), uentry_unparse (ue)),
2578 uentry_whereLast (ue));
2581 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2583 /* start modifications */
2584 else if( qual_isBufQualifier(qel) ) {
2585 ctype ct = ctype_realType(uentry_getType(ue));
2586 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2588 if( uentry_hasBufStateInfo(ue) ) {
2589 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2591 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2592 /* If formal func param */
2593 uentry_setNullTerminatedState(ue);
2594 uentry_setLen (ue, 1);
2595 uentry_setSize (ue, 1);
2597 sRef_setNullTerminatedState(uentry_getSref(ue));
2598 sRef_setLen (uentry_getSref(ue), 1);
2599 sRef_setSize (uentry_getSref(ue), 1);
2601 uentry_setPossiblyNullTerminatedState(ue);
2603 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2607 /* put other BufState Qualifiers here */
2609 cstring s = uentry_getName(ue);
2610 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2611 struct for identifier %s\n", s) );
2613 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2615 sRef retSref = uentry_getSref (ue);
2616 ctype retType = sRef_getType (retSref);
2618 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2619 sRef_setNullTerminatedState (retSref);
2625 message ("Qualifier %s used on non-pointer on \
2626 function return: %q", qual_unparse (qel),
2627 uentry_unparse (ue)));
2634 message ("Qualifier %s used on non-pointer: %q",
2635 qual_unparse (qel), uentry_unparse (ue)));
2637 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2639 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2641 ctype realType = ctype_realType (ue->utype);
2642 sstate defstate = sstate_fromQual (qel);
2644 if (ctype_isFunction (realType))
2646 realType = ctype_realType (ctype_getReturnType (realType));
2649 if (qual_isRelDef (qel))
2651 ; /* okay anywhere */
2655 if (!ctype_isAP (realType)
2656 && !ctype_isSU (realType)
2657 && !ctype_isUnknown (realType)
2658 && !ctype_isAbstract (ue->utype))
2661 (FLG_ANNOTATIONERROR,
2662 message ("Qualifier %s used on non-pointer or struct: %q",
2663 qual_unparse (qel), uentry_unparse (ue)),
2664 uentry_whereLast (ue));
2668 uentry_setDefState (ue, defstate);
2670 if (sRef_isStateSpecial (ue->sref)
2671 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2673 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2676 else if (qual_isYield (qel))
2678 if (uentry_isVariable (ue))
2680 ue->info->var->kind = VKYIELDPARAM;
2685 (FLG_ANNOTATIONERROR,
2686 message ("Qualifier %s used on non-iterator parameter: %q",
2687 qual_unparse (qel), uentry_unparse (ue)),
2688 uentry_whereLast (ue));
2691 else if (qual_isExQual (qel))
2693 exkind ek = exkind_fromQual (qel);
2694 ctype ut = uentry_getType (ue);
2696 DPRINTF (("Reflect ex qual: %s / %s",
2697 uentry_unparse (ue), exkind_unparse (ek)));
2699 if (ctype_isFunction (ut))
2701 ut = ctype_getReturnType (ut);
2704 if (!(ctype_isVisiblySharable (ut))
2705 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2706 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2708 if (!qual_isImplied (qel))
2710 if (ctype_isImmutableAbstract (ut)) {
2712 (FLG_REDUNDANTSHAREQUAL,
2713 message ("Qualifier %s used on unsharable storage type %t: %q",
2714 exkind_unparse (ek), ut, uentry_getName (ue)),
2715 uentry_whereLast (ue));
2718 (FLG_MISPLACEDSHAREQUAL,
2719 message ("Qualifier %s used on unsharable storage type %t: %q",
2720 exkind_unparse (ek), ut, uentry_getName (ue)),
2721 uentry_whereLast (ue));
2727 alkind ak = sRef_getAliasKind (ue->sref);
2729 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2730 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2732 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2734 if (!alkind_isTemp (ak))
2736 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2737 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2740 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2741 || alkind_isOwned (ak))
2749 message ("Exposure qualifier %s used on %s storage (should "
2750 "be dependent): %q",
2752 alkind_unparse (ak),
2753 uentry_unparse (ue)));
2757 else if (qual_isGlobCheck (qel))
2759 if (uentry_isVariable (ue))
2761 chkind ch = chkind_fromQual (qel);
2763 if (ue->info->var->checked != CH_UNKNOWN)
2765 if (ch == ue->info->var->checked)
2767 llerror (FLG_SYNTAX,
2768 message ("Redundant %s qualifier on %q",
2770 uentry_getName (ue)));
2774 llerror (FLG_SYNTAX,
2776 ("Contradictory %s and %s qualifiers on %q",
2778 checkedName (ue->info->var->checked),
2779 uentry_getName (ue)));
2783 ue->info->var->checked = ch;
2789 message ("Qualifier %s used with non-variable",
2790 qual_unparse (qel)));
2793 else if (qual_isReturned (qel))
2795 if (uentry_isVariable (ue))
2797 ue->info->var->kind = VKRETPARAM;
2801 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2802 qual_unparse (qel)));
2807 uentry_reflectOtherQualifier (ue, qel);
2810 sRef_storeState (ue->sref);
2811 } end_qualList_elements;
2815 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2819 uentry_isOnly (uentry ue)
2821 return (!uentry_isUndefined (ue)
2822 && uentry_isVariable (ue)
2823 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2827 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2829 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2830 sRef_setOrigAliasKind (ue->sref, ak);
2834 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2836 if (uentry_isVariable (ue))
2838 ue->info->var->nullstate = ns;
2841 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2845 uentry_isUnique (uentry ue)
2847 return (!uentry_isUndefined (ue)
2848 && uentry_isVariable (ue)
2849 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2853 uentry_isFileStatic (uentry ue)
2855 return (uentry_isStatic (ue)
2856 && (!uentry_isVariable (ue)
2857 || sRef_isFileStatic (uentry_getSref (ue))));
2861 uentry_isExported (uentry ue)
2863 if (uentry_isValid (ue))
2865 if (uentry_isVariable (ue))
2867 return (sRef_isRealGlobal (uentry_getSref (ue)));
2871 return !uentry_isStatic (ue);
2879 uentry_isNonLocal (uentry ue)
2881 return (uentry_isValid (ue) && uentry_isVariable (ue)
2882 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2886 uentry_isGlobalVariable (uentry ue)
2888 return (uentry_isValid (ue) && uentry_isVariable (ue)
2889 && sRef_isFileOrGlobalScope (ue->sref));
2893 uentry_isVisibleExternally (uentry ue)
2895 return (uentry_isValid (ue)
2896 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2897 || (!uentry_isStatic (ue)
2898 && (uentry_isFunction (ue)
2899 || uentry_isIter (ue)
2900 || uentry_isEndIter (ue)
2901 || uentry_isConstant (ue)
2902 || uentry_isDatatype (ue)
2903 || uentry_isAnyTag (ue)))));
2907 uentry_isPrintfLike (uentry ue)
2909 return (uentry_isFunction (ue)
2910 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2914 uentry_isScanfLike (uentry ue)
2916 return (uentry_isFunction (ue)
2917 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2921 uentry_isMessageLike (uentry ue)
2923 return (uentry_isFunction (ue)
2924 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2927 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2929 uentryList args = uentry_getParams (ue);
2931 if (!uentryList_isMissingParams (args))
2933 uentry last = uentry_undefined;
2935 uentryList_elements (args, current)
2937 if (uentry_isElipsisMarker (current))
2939 if (uentry_isUndefined (last))
2943 message ("Function %q is marked %s, but has no format "
2944 "string argument before elipsis",
2945 uentry_getName (ue),
2946 specCode_unparse (ue->info->fcn->specialCode)),
2947 uentry_whereLast (ue));
2948 ue->info->fcn->specialCode = SPC_NONE;
2952 ctype rt = ctype_realType (uentry_getType (last));
2954 if (!ctype_match (rt, ctype_string))
2958 /* wchar_t * is okay too */
2959 if (ctype_isAP (rt))
2961 ctype base = ctype_baseArrayPtr (rt);
2963 if (ctype_isArbitraryIntegral (base))
2973 message ("Function %q is marked %s, but the argument "
2974 "before the elipsis has type %s (should be char *)",
2975 uentry_getName (ue),
2976 specCode_unparse (ue->info->fcn->specialCode),
2977 ctype_unparse (uentry_getType (last))),
2978 uentry_whereLast (ue));
2980 ue->info->fcn->specialCode = SPC_NONE;
2987 } end_uentryList_elements ;
2991 message ("Function %q is marked %s, but has no elipsis parameter",
2992 uentry_getName (ue),
2993 specCode_unparse (ue->info->fcn->specialCode)),
2994 uentry_whereLast (ue));
2996 ue->info->fcn->specialCode = SPC_NONE;
3001 uentry_setPrintfLike (uentry ue)
3003 uentry_convertVarFunction (ue);
3004 llassertfatal (uentry_isFunction (ue));
3005 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3006 checkSpecialFunction (ue);
3010 uentry_setScanfLike (uentry ue)
3012 uentry_convertVarFunction (ue);
3013 llassertfatal (uentry_isFunction (ue));
3014 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3015 checkSpecialFunction (ue);
3019 uentry_setMessageLike (uentry ue)
3021 uentry_convertVarFunction (ue);
3022 llassertfatal (uentry_isFunction (ue));
3023 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3024 checkSpecialFunction (ue);
3028 uentry_isSpecialFunction (uentry ue)
3030 return (uentry_isFunction (ue)
3031 && (ue->info->fcn->specialCode != SPC_NONE));
3034 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3036 ctype ct = idDecl_getCtype (t);
3038 fileloc loc = setLocation ();
3039 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3040 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3042 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3043 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3044 uentry_implicitParamAnnots (ue);
3046 /* Parameter type [][] or [x][] is invalid */
3048 while (ctype_isFixedArray (base)) {
3049 base = ctype_baseArrayPtr (base);
3052 if (ctype_isIncompleteArray (base)) {
3053 base = ctype_baseArrayPtr (base);
3055 if (ctype_isArray (base)) {
3056 if (!uentry_hasName (ue)) {
3057 (void) optgenerror (FLG_INCOMPLETETYPE,
3058 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3060 ctype_unparse (ct)),
3061 uentry_whereLast (ue));
3063 (void) optgenerror (FLG_INCOMPLETETYPE,
3064 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3065 uentry_getName (ue),
3066 ctype_unparse (ct)),
3067 uentry_whereLast (ue));
3072 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3076 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3078 ctype ct = idDecl_getCtype (t);
3080 if (ctype_isFunction (ct))
3082 return (uentry_makeIdFunction (t));
3086 fileloc loc = setLocation ();
3087 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3089 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3091 if (!uentry_isExtern (ue))
3093 uentry_setDefined (ue, loc);
3101 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3103 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3111 static /*@only@*/ /*@notnull@*/
3112 uentry uentry_makeConstantAux (cstring n, ctype t,
3113 /*@keep@*/ fileloc f, bool priv, bool macro,
3114 /*@only@*/ multiVal m)
3116 uentry e = uentry_alloc ();
3119 e->uname = cstring_copy (n);
3121 e->storageclass = SCNONE;
3123 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3125 e->sref = sRef_makeConst (t);
3130 e->uses = filelocList_new ();
3131 e->isPrivate = priv;
3132 e->hasNameError = FALSE;
3134 e->info = (uinfo) dmalloc (sizeof (*e->info));
3135 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3136 e->info->uconst->access = typeIdSet_undefined;
3137 e->info->uconst->macro = macro;
3139 uentry_setSpecDef (e, f);
3141 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3143 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3146 uentry_setConstantValue (e, m);
3151 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3153 return (uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ()));
3156 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3158 return (uentry_makeConstantAux (n, t, f, priv, FALSE, val));
3161 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3163 return (uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ()));
3166 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3168 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3169 idDecl_getCtype (t),
3172 llassert (fileloc_isUndefined (ue->whereDeclared));
3173 ue->whereDeclared = setLocation ();
3174 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3176 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3177 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3185 void uentry_setDefState (uentry ue, sstate defstate)
3187 if (uentry_isValid (ue))
3189 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3191 if (uentry_isVariable (ue))
3193 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3198 bool uentry_isCheckedUnknown (uentry ue)
3200 return (uentry_isVar (ue)
3201 && (ue->info->var->checked == CH_UNKNOWN));
3204 bool uentry_isCheckMod (uentry ue)
3206 return (uentry_isVar (ue)
3207 && (ue->info->var->checked == CH_CHECKMOD));
3210 bool uentry_isUnchecked (uentry ue)
3212 return (uentry_isVar (ue)
3213 && (ue->info->var->checked == CH_UNCHECKED));
3216 bool uentry_isChecked (uentry ue)
3218 return (uentry_isVar (ue)
3219 && (ue->info->var->checked == CH_CHECKED));
3222 bool uentry_isCheckedModify (uentry ue)
3224 return (uentry_isVar (ue)
3225 && (ue->info->var->checked == CH_CHECKED
3226 || ue->info->var->checked == CH_CHECKMOD
3227 || ue->info->var->checked == CH_CHECKEDSTRICT));
3230 bool uentry_isCheckedStrict (uentry ue)
3232 return (uentry_isVar (ue)
3233 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3236 void uentry_setUnchecked (uentry ue)
3238 llassert (uentry_isVar (ue));
3240 ue->info->var->checked = CH_UNCHECKED;
3243 void uentry_setChecked (uentry ue)
3245 llassert (uentry_isVar (ue));
3247 ue->info->var->checked = CH_CHECKED;
3250 void uentry_setCheckMod (uentry ue)
3252 llassert (uentry_isVar (ue));
3254 ue->info->var->checked = CH_CHECKMOD;
3257 void uentry_setCheckedStrict (uentry ue)
3259 llassert (uentry_isVar (ue));
3261 ue->info->var->checked = CH_CHECKEDSTRICT;
3264 static /*@only@*/ /*@notnull@*/
3265 uentry uentry_makeVariableAux (cstring n, ctype t,
3267 /*@exposed@*/ sRef s,
3268 bool priv, vkind kind)
3270 uentry e = uentry_alloc ();
3273 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3276 e->uname = cstring_copy (n);
3279 e->storageclass = SCNONE;
3281 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3288 e->uses = filelocList_new ();
3289 e->isPrivate = priv;
3290 e->hasNameError = FALSE;
3292 e->info = (uinfo) dmalloc (sizeof (*e->info));
3293 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3294 e->info->var->kind = kind;
3296 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3297 e->info->var->checked = CH_UNKNOWN;
3299 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3300 uentry_setSpecDef (e, f);
3301 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3303 if (ctype_isFunction (rt))
3305 rt = ctype_getReturnType (rt);
3308 if (ctype_isUA (rt))
3310 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3311 sRef_setStateFromType (e->sref, rt);
3314 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3315 e->info->var->defstate = sRef_getDefState (e->sref);
3316 e->info->var->nullstate = sRef_getNullState (e->sref);
3318 /* start modifications */
3319 /* This function sets the uentry for a pointer or array variable declaration,
3320 it allocates memory and sets the fields. We check if the type of the variable
3321 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3323 if( ctype_isArray (t) || ctype_isPointer(t)) {
3324 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3325 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3326 /*@access sRef@*/ /*i@222*/
3327 /* It probably isn't necessary to violate the abstraction here
3330 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
3333 e->info->var->bufinfo = NULL;
3335 /* end modification */
3341 uentry_isYield (uentry ue)
3343 return (uentry_isVariable (ue)
3344 && (ue->info->var->kind == VKYIELDPARAM
3345 || ue->info->var->kind == VKREFYIELDPARAM));
3349 uentry_isRefsField (uentry ue)
3351 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3354 /*@only@*/ /*@notnull@*/
3355 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3357 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3358 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3365 void uentry_makeVarFunction (uentry ue)
3372 llassert (uentry_isValid (ue));
3373 llassert (!sRef_modInFunction ());
3375 ak = sRef_getOrigAliasKind (ue->sref);
3376 ek = sRef_getOrigExKind (ue->sref);
3378 llassert (uentry_isVariable (ue));
3379 oldInfo = ue->info->var;
3381 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3382 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3385 ** expanded macro is marked used
3388 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3391 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3392 ue->info->fcn->exitCode = XK_UNKNOWN;
3393 ue->info->fcn->nullPred = qual_createUnknown ();
3394 ue->info->fcn->specialCode = SPC_NONE;
3395 ue->info->fcn->access = typeIdSet_undefined;
3396 ue->info->fcn->hasGlobs = FALSE;
3397 ue->info->fcn->globs = globSet_undefined;
3398 ue->info->fcn->hasMods = FALSE;
3399 ue->info->fcn->mods = sRefSet_undefined;
3400 ue->info->fcn->specclauses = NULL;
3401 ue->info->fcn->defparams = uentryList_undefined;
3404 ue->info->fcn->preconditions = functionConstraint_undefined;
3408 ue->info->fcn->postconditions = functionConstraint_undefined;
3411 if (ctype_isFunction (ue->utype))
3413 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3417 ue->sref = sRef_makeType (ctype_unknown);
3420 if (sRef_isRefCounted (ue->sref))
3426 if (alkind_isUnknown (ak))
3428 if (exkind_isKnown (ek))
3430 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3431 ak = AK_IMPDEPENDENT;
3435 if (context_getFlag (FLG_RETIMPONLY))
3437 if (ctype_isFunction (ue->utype)
3438 && ctype_isVisiblySharable
3439 (ctype_realType (ctype_getReturnType (ue->utype))))
3441 if (uentryList_hasReturned (uentry_getParams (ue)))
3447 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3462 loc = ue->whereDeclared;
3464 sRef_setAliasKind (ue->sref, ak, loc);
3465 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3466 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3467 sRef_setExKind (ue->sref, ek, loc);
3469 if (oldInfo->kind == VKEXPMACRO)
3475 fileloc_free (ue->whereDefined);
3476 ue->whereDefined = fileloc_undefined;
3479 uvinfo_free (oldInfo);
3482 void uentry_makeConstantFunction (uentry ue)
3489 llassert (uentry_isValid (ue));
3490 llassert (!sRef_modInFunction ());
3492 ak = sRef_getOrigAliasKind (ue->sref);
3493 ek = sRef_getOrigExKind (ue->sref);
3495 llassert (uentry_isConstant (ue));
3496 oldInfo = ue->info->uconst;
3498 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3501 ** expanded macro is marked used (until I write a pre-processor)
3505 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3506 ue->info->fcn->exitCode = XK_UNKNOWN;
3507 ue->info->fcn->nullPred = qual_createUnknown ();
3508 ue->info->fcn->specialCode = SPC_NONE;
3509 ue->info->fcn->access = typeIdSet_undefined;
3510 ue->info->fcn->hasGlobs = FALSE;
3511 ue->info->fcn->globs = globSet_undefined;
3512 ue->info->fcn->hasMods = FALSE;
3513 ue->info->fcn->mods = sRefSet_undefined;
3514 ue->info->fcn->specclauses = NULL;
3515 ue->info->fcn->defparams = uentryList_undefined;
3518 ue->info->fcn->preconditions = functionConstraint_undefined;
3522 ue->info->fcn->postconditions = functionConstraint_undefined;
3526 if (ctype_isFunction (ue->utype))
3528 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3532 ue->sref = sRef_makeType (ctype_unknown);
3535 if (sRef_isRefCounted (ue->sref))
3541 if (alkind_isUnknown (ak))
3543 if (exkind_isKnown (ek))
3545 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3546 ak = AK_IMPDEPENDENT;
3550 if (context_getFlag (FLG_RETIMPONLY))
3552 if (ctype_isFunction (ue->utype)
3553 && ctype_isVisiblySharable
3554 (ctype_realType (ctype_getReturnType (ue->utype))))
3556 if (uentryList_hasReturned (uentry_getParams (ue)))
3562 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3577 loc = ue->whereDeclared;
3579 sRef_setAliasKind (ue->sref, ak, loc);
3580 sRef_setExKind (ue->sref, ek, loc);
3582 fileloc_free (ue->whereDefined);
3583 ue->whereDefined = fileloc_undefined;
3584 ucinfo_free (oldInfo);
3588 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3590 llassert (uentry_isValid (ue));
3592 if (uentry_isIter (ue))
3594 llassert (globSet_isUndefined (ue->info->iter->globs));
3595 ue->info->iter->globs = globs;
3599 uentry_convertVarFunction (ue);
3601 llassert (uentry_isFunction (ue));
3602 llassert (!ue->info->fcn->hasGlobs
3603 && globSet_isUndefined (ue->info->fcn->globs));
3605 ue->info->fcn->hasGlobs = TRUE;
3606 globSet_markImmutable (globs);
3607 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3612 /* ??? - evans 2001-09-09 not sure what's going on here...?
3613 if (globSet_hasStatic (globs))
3615 context_recordFileGlobals (globs);
3619 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3621 ue->info->fcn->hasMods = TRUE;
3625 void uentry_addAccessType (uentry ue, typeId tid)
3627 if (uentry_isFunction (ue))
3629 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3631 else if (uentry_isEitherConstant (ue))
3633 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3635 else if (uentry_isIter (ue))
3637 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3639 else if (uentry_isEndIter (ue))
3641 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3645 llbug (message ("no access for: %q", uentry_unparse (ue)));
3649 /*@only@*/ /*@notnull@*/ uentry
3650 uentry_makeFunction (cstring n, ctype t,
3652 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3653 /*@only@*/ warnClause warn,
3656 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3657 return (uentry_makeFunctionAux (n, t,
3658 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3659 : typeIdSet_single (access)),
3666 /*@notnull@*/ uentry
3667 uentry_makePrivFunction2 (cstring n, ctype t,
3669 globSet globs, sRefSet mods,
3672 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3677 /*@notnull@*/ uentry
3678 uentry_makeSpecFunction (cstring n, ctype t,
3680 /*@only@*/ globSet globs,
3681 /*@only@*/ sRefSet mods,
3684 uentry ue = uentry_makeFunctionAux (n, t, access,
3685 globs, mods, warnClause_undefined,
3688 uentry_setHasGlobs (ue);
3689 uentry_setHasMods (ue);
3691 reflectImplicitFunctionQualifiers (ue, TRUE);
3696 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3698 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3699 sRef_undefined, FALSE, VKEXPMACRO);
3701 uentry_setDefined (ue, f);
3705 /*@notnull@*/ /*@notnull@*/ uentry
3706 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3708 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3709 typeIdSet_singleOpt (access),
3710 globSet_undefined, sRefSet_undefined,
3711 warnClause_undefined,
3715 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3719 bool uentry_isForward (uentry e)
3721 if (uentry_isValid (e))
3723 ctype ct = uentry_getType (e);
3725 return (ctype_isUnknown (ct)
3726 || (ctype_isFunction (ct)
3727 && ctype_isUnknown (ctype_getReturnType (ct))));
3734 /*@notnull@*/ uentry
3735 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3737 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3738 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3742 /*@notnull@*/ uentry
3743 uentry_makeUnspecFunction (cstring n, ctype t,
3747 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3748 sRefSet_undefined, warnClause_undefined,
3751 reflectImplicitFunctionQualifiers (ue, TRUE);
3760 /* is exported for use by usymtab_interface */
3762 /*@notnull@*/ uentry
3763 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3764 fileloc f, bool priv)
3766 uentry e = uentry_alloc ();
3768 DPRINTF (("Make datatype: %s / %s",
3769 n, ctype_unparse (t)));
3771 /* e->shallowCopy = FALSE; */
3772 e->ukind = KDATATYPE;
3773 e->uname = cstring_copy (n);
3775 e->storageclass = SCNONE;
3776 e->sref = sRef_makeUnknown ();
3780 sRef_setStateFromType (e->sref, t);
3783 uentry_setSpecDef (e, f);
3785 e->warn = warnClause_undefined; /*@i634@*/
3786 e->uses = filelocList_new ();
3787 e->isPrivate = priv;
3788 e->hasNameError = FALSE;
3793 e->info = (uinfo) dmalloc (sizeof (*e->info));
3794 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3795 e->info->datatype->abs = abstract;
3796 e->info->datatype->mut = mut;
3797 e->info->datatype->type = ctype_undefined;
3799 if (uentry_isDeclared (e))
3801 uentry_setDefined (e, f);
3804 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3806 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3812 /*@notnull@*/ uentry
3813 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3815 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3818 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3820 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3821 ctype_bool, NO, abstract,
3822 fileloc_getBuiltin (),
3825 ret->info->datatype->type = ctype_bool;
3833 static /*@only@*/ /*@notnull@*/ uentry
3834 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3835 /*@only@*/ fileloc f)
3837 uentry e = uentry_alloc ();
3840 e->uname = cstring_copy (n);
3842 e->sref = sRef_makeUnknown ();
3843 e->storageclass = SCNONE;
3847 uentry_setSpecDef (e, f);
3849 e->warn = warnClause_undefined; /*@i452@*/
3850 e->uses = filelocList_new ();
3851 e->isPrivate = FALSE;
3852 e->hasNameError = FALSE;
3854 e->info = (uinfo) dmalloc (sizeof (*e->info));
3855 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3856 e->info->iter->access = access;
3857 e->info->iter->mods = sRefSet_undefined;
3858 e->info->iter->globs = globSet_undefined;
3860 uentry_checkIterArgs (e);
3864 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3866 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3869 static /*@notnull@*/ uentry
3870 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3872 uentry e = uentry_alloc ();
3874 /* e->shallowCopy = FALSE; */
3875 e->ukind = KENDITER;
3876 e->storageclass = SCNONE;
3877 e->uname = message ("end_%s", n);
3878 e->utype = ctype_unknown;
3879 e->sref = sRef_makeUnknown ();
3881 uentry_setSpecDef (e, f);
3886 e->uses = filelocList_new ();
3887 e->isPrivate = FALSE;
3888 e->hasNameError = FALSE;
3890 e->info = (uinfo) dmalloc (sizeof (*e->info));
3891 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3893 e->info->enditer->access = access;
3895 e->warn = warnClause_undefined; /*@i452@*/
3899 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3901 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3908 static /*@only@*/ /*@notnull@*/ uentry
3909 uentry_makeTagAux (cstring n, ctype t,
3910 /*@only@*/ fileloc fl,
3911 bool priv, ekind kind)
3913 uentry e = uentry_alloc ();
3915 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3917 llbuglit ("uentry_makeTagAux: not a tag type");
3921 /* e->shallowCopy = FALSE; */
3922 e->uname = cstring_copy (n);
3925 e->sref = sRef_makeUnknown ();
3926 e->storageclass = SCNONE;
3928 uentry_setSpecDef (e, fl);
3933 e->uses = filelocList_new ();
3934 e->isPrivate = priv;
3935 e->hasNameError = FALSE;
3937 e->info = (uinfo) dmalloc (sizeof (*e->info));
3938 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3939 e->info->datatype->abs = NO;
3940 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3941 e->info->datatype->type = t;
3942 e->warn = warnClause_undefined; /*@i452@*/
3944 if (uentry_isDeclared (e))
3946 uentry_setDefined (e, fl);
3952 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3954 cstring sname = makeStruct (n);
3955 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3957 cstring_free (sname);
3962 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3964 cstring sname = makeStruct (n);
3965 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3967 cstring_free (sname);
3972 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3974 cstring uname = makeUnion (n);
3975 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3977 cstring_free (uname);
3983 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3985 cstring ename = makeEnum (n);
3986 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3988 cstring_free (ename);
3994 uentry_makeUnionTagLoc (cstring n, ctype t)
3996 cstring uname = makeUnion (n);
3997 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3999 cstring_free (uname);
4004 uentry_makeEnumTagLoc (cstring n, ctype t)
4006 cstring ename = makeEnum (n);
4007 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4009 cstring_free (ename);
4014 uentry_isStructTag (uentry ue)
4016 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4020 uentry_isUnionTag (uentry ue)
4022 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4026 uentry_isEnumTag (uentry ue)
4028 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4032 uentry_isAnyTag (uentry ue)
4034 return (uentry_isStructTag (ue)
4035 || uentry_isUnionTag (ue)
4036 || uentry_isEnumTag (ue));
4039 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4041 extern void uentry_destroyMod (void)
4042 /*@globals killed emarker@*/ /*@modifies emarker@*/
4044 static bool wasDestroyed = FALSE;
4046 llassert (!wasDestroyed);
4048 if (emarker != NULL)
4050 uentry_reallyFree (emarker);
4053 wasDestroyed = TRUE;
4057 uentry_makeElipsisMarker (void)
4059 if (emarker == NULL)
4061 emarker = uentry_alloc ();
4063 emarker->ukind = KELIPSMARKER;
4064 emarker->uname = cstring_makeLiteral ("...");
4065 emarker->utype = ctype_elipsMarker;
4066 emarker->sref = sRef_undefined;
4067 emarker->storageclass = SCNONE;
4068 emarker->used = FALSE;
4069 emarker->lset = FALSE;
4070 emarker->info = NULL;
4072 uentry_setSpecDef (emarker, fileloc_undefined);
4073 emarker->uses = filelocList_new ();
4074 emarker->isPrivate = FALSE;
4075 emarker->hasNameError = FALSE;
4078 /*@ignore@*/ return (emarker); /*@end@*/
4086 uentry_equiv (uentry p1, uentry p2)
4088 if (uentry_compare (p1, p2) != 0)
4099 uentry_xcomparealpha (uentry *p1, uentry *p2)
4103 if ((res = uentry_compare (*p1, *p2)) == 0) {
4104 if ((*p1 != NULL) && (*p2 != NULL)) {
4105 res = cstring_compare ((*p1)->uname,
4114 uentry_xcompareuses (uentry *p1, uentry *p2)
4119 if (uentry_isValid (u1))
4121 if (uentry_isValid (u2))
4123 return (-1 * int_compare (filelocList_size (u1->uses),
4124 filelocList_size (u2->uses)));
4133 if (uentry_isValid (u2))
4145 uentry_compareStrict (uentry v1, uentry v2)
4147 COMPARERETURN (uentry_compare (v1, v2));
4149 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4151 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4152 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4153 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4160 uentry_compare (uentry u1, uentry u2)
4162 if (u1 == u2) return 0;
4164 if (uentry_isInvalid (u1)) return -1;
4165 if (uentry_isInvalid (u2)) return 1;
4167 INTCOMPARERETURN (u1->ukind, u2->ukind);
4168 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4169 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4170 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4176 /* bug detected by splint:
4177 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4182 return (multiVal_compare (uentry_getConstantValue (u1),
4183 uentry_getConstantValue (u2)));
4187 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4189 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4190 uentry_accessType (u2)));
4191 return (uentryList_compareParams (uentry_getParams (u1),
4192 uentry_getParams (u2)));
4194 return (typeIdSet_compare (uentry_accessType (u1),
4195 uentry_accessType (u2)));
4198 ** Functions are never equivalent
4201 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4211 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4212 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4213 sRef_getOrigAliasKind (u2->sref)));
4214 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4215 sRef_getOrigExKind (u2->sref)));
4216 COMPARERETURN (generic_compare (u1->info->var->checked,
4217 u2->info->var->checked));
4218 COMPARERETURN (generic_compare (u1->info->var->defstate,
4219 u2->info->var->defstate));
4220 return (generic_compare (u1->info->var->nullstate,
4221 u2->info->var->nullstate));
4223 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4224 u2->info->datatype->type));
4225 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4226 u2->info->datatype->mut));
4227 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4236 ** all entries are: <type>[@<info>]*#<name>
4238 ** info depends on kind:
4242 advanceField (char **s)
4244 reader_checkChar (s, '@');
4248 advanceName (char **s)
4250 reader_checkChar (s, '#');
4254 vkind_fromInt (int i)
4256 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4258 llbuglit ("vkind_fromInt: out of range");
4265 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4266 typeIdSet access, nstate nullstate,
4267 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4269 uentry e = uentry_alloc ();
4274 e->sref = sRef_makeConst (ct);
4276 sRef_setNullState (e->sref, nullstate, loc);
4277 e->storageclass = SCNONE;
4279 if (fileloc_isSpec (loc))
4281 e->whereSpecified = loc;
4282 e->whereDeclared = fileloc_undefined;
4286 e->whereSpecified = fileloc_undefined;
4287 e->whereDeclared = loc;
4290 e->whereDefined = fileloc_undefined;
4291 e->uses = filelocList_new ();
4292 e->isPrivate = FALSE;
4293 e->hasNameError = FALSE;
4298 e->warn = warnClause_undefined; /*@i452@*/
4300 e->info = (uinfo) dmalloc (sizeof (*e->info));
4301 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4302 e->info->uconst->access = access;
4303 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4304 uentry_setConstantValue (e, m);
4305 sRef_storeState (e->sref);
4310 static /*@only@*/ uentry
4311 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4312 sstate defstate, nstate isnull, alkind aliased,
4313 exkind exp, chkind checked,
4314 /*@only@*/ fileloc loc)
4316 uentry e = uentry_alloc ();
4321 e->storageclass = SCNONE;
4323 e->sref = sRef_makeType (ct);
4324 sRef_setNullState (e->sref, isnull, loc);
4326 e->whereDefined = fileloc_undefined;
4328 if (fileloc_isSpec (loc))
4330 e->whereSpecified = loc;
4331 e->whereDeclared = fileloc_undefined;
4335 e->whereSpecified = fileloc_undefined;
4336 e->whereDeclared = loc;
4339 e->isPrivate = FALSE;
4340 e->hasNameError = FALSE;
4345 e->uses = filelocList_new ();
4346 e->warn = warnClause_undefined; /*@i452@*/
4348 e->info = (uinfo) dmalloc (sizeof (*e->info));
4349 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4350 e->info->var->kind = kind;
4351 e->info->var->checked = checked;
4352 e->info->var->defstate = defstate;
4354 sRef_setDefState (e->sref, defstate, loc);
4356 e->info->var->nullstate = sRef_getNullState (e->sref);
4358 sRef_setExKind (e->sref, exp, loc);
4359 sRef_setAliasKind (e->sref, aliased, loc);
4361 sRef_storeState (e->sref);
4363 /*DRL ADDED 9-1-2000 */
4364 e->info->var->bufinfo = NULL;
4369 static /*@only@*/ uentry
4370 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4371 ynm mut, ctype rtype, alkind ak, exkind exp,
4372 sstate defstate, nstate isnull,
4373 /*@only@*/ fileloc loc)
4375 uentry e = uentry_alloc ();
4377 e->ukind = KDATATYPE;
4378 /* e->shallowCopy = FALSE; */
4381 e->storageclass = SCNONE;
4382 e->sref = sRef_makeUnknown ();
4383 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4386 ** This is only setting null state. (I think?)
4389 if (ctype_isUA (ct))
4391 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4393 if (uentry_isValid (te))
4395 sRef_setStateFromUentry (e->sref, te);
4399 /* problem for recursive type definitions */
4403 sRef_setAliasKind (e->sref, ak, loc);
4404 sRef_setExKind (e->sref, exp, loc);
4406 sRef_setDefState (e->sref, defstate, loc);
4408 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4410 isnull = NS_ABSNULL;
4413 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4414 sRef_mergeNullState (e->sref, isnull);
4416 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4418 if (fileloc_isSpec (loc))
4420 e->whereSpecified = loc;
4421 e->whereDeclared = fileloc_undefined;
4425 e->whereSpecified = fileloc_undefined;
4426 e->whereDeclared = loc;
4429 e->isPrivate = FALSE;
4430 e->hasNameError = FALSE;
4432 e->warn = warnClause_undefined; /*@i452@*/
4436 e->uses = filelocList_new ();
4438 e->info = (uinfo) dmalloc (sizeof (*e->info));
4439 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4440 e->info->datatype->abs = abstract;
4441 e->info->datatype->mut = mut;
4442 e->info->datatype->type = rtype;
4444 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4445 sRef_storeState (e->sref);
4446 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4452 static void uentry_setHasGlobs (uentry ue)
4454 llassert (uentry_isFunction (ue));
4456 ue->info->fcn->hasGlobs = TRUE;
4459 static void uentry_setHasMods (uentry ue)
4461 llassert (uentry_isFunction (ue));
4463 ue->info->fcn->hasMods = TRUE;
4467 bool uentry_hasGlobs (uentry ue)
4469 if (uentry_isFunction (ue))
4471 return (ue->info->fcn->hasGlobs);
4477 bool uentry_hasStateClauseList (uentry ue)
4479 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4482 bool uentry_hasConditions (uentry ue)
4484 return (uentry_isFunction (ue)
4485 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4486 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4489 stateClauseList uentry_getStateClauseList (uentry ue)
4491 if (!uentry_isFunction (ue))
4493 llassert (uentry_isFunction (ue));
4494 return stateClauseList_undefined;
4497 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4498 return ue->info->fcn->specclauses;
4501 bool uentry_hasMods (uentry ue)
4503 if (uentry_isFunction (ue))
4505 return (ue->info->fcn->hasMods);
4512 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4514 bool hasGlobs, /*@only@*/ globSet globs,
4515 bool hasMods, /*@only@*/ sRefSet mods,
4516 alkind ak, exkind exp,
4517 sstate defstate, nstate isnull,
4521 /*@only@*/ stateClauseList specclauses,
4522 /*@only@*/ warnClause warnclause,
4523 /*@only@*/ fileloc loc)
4525 uentry e = uentry_alloc ();
4528 /* e->shallowCopy = FALSE; */
4532 e->storageclass = SCNONE;
4534 if (ctype_isFunction (ct))
4536 ret = ctype_getReturnType (ct);
4540 if (ctype_isKnown (ct))
4542 llbug (message ("not function: %s", ctype_unparse (ct)));
4545 ret = ctype_unknown;
4548 e->sref = sRef_makeType (ret);
4550 if (ctype_isUA (ret))
4552 sRef_setStateFromType (e->sref, ret);
4555 sRef_setDefined (e->sref, loc);
4556 sRef_setNullState (e->sref, isnull, loc);
4558 sRef_setAliasKind (e->sref, ak, loc);
4559 sRef_setExKind (e->sref, exp, loc);
4560 sRef_setDefState (e->sref, defstate, loc);
4562 e->whereSpecified = loc;
4563 e->whereDefined = fileloc_undefined;
4565 e->isPrivate = FALSE;
4566 e->hasNameError = FALSE;
4570 e->uses = filelocList_new ();
4571 e->warn = warnclause;
4573 e->info = (uinfo) dmalloc (sizeof (*e->info));
4574 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4576 e->info->fcn->exitCode = exitCode;
4577 e->info->fcn->specialCode = sCode;
4578 e->info->fcn->nullPred = nullPred;
4579 e->info->fcn->access = access;
4581 e->info->fcn->specclauses = specclauses;
4582 e->info->fcn->hasGlobs = hasGlobs;
4583 e->info->fcn->globs = globs;
4585 e->info->fcn->hasMods = hasMods;
4586 e->info->fcn->mods = mods;
4588 e->info->fcn->defparams = uentryList_undefined;
4589 e->whereDeclared = fileloc_undefined;
4591 sRef_storeState (e->sref);
4594 e->info->fcn->preconditions = NULL;
4598 e->info->fcn->postconditions = NULL;
4604 static /*@only@*/ uentry
4605 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4606 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4608 uentry e = uentry_alloc ();
4610 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4612 llbuglit ("uentry_makeTagBase: not a tag type");
4615 /* e->shallowCopy = FALSE; */
4619 e->sref = sRef_makeUnknown ();
4620 e->storageclass = SCNONE;
4622 if (fileloc_isSpec (loc))
4624 e->whereSpecified = loc;
4625 e->whereDeclared = fileloc_undefined;
4629 e->whereDeclared = loc;
4630 e->whereSpecified = fileloc_undefined;
4633 e->whereDefined = fileloc_undefined;
4635 e->isPrivate = FALSE;
4636 e->hasNameError = FALSE;
4640 e->uses = filelocList_new ();
4641 e->warn = warnClause_undefined; /*@i452@*/
4643 e->info = (uinfo) dmalloc (sizeof (*e->info));
4644 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4645 e->info->datatype->abs = NO;
4646 e->info->datatype->mut = MAYBE;
4647 e->info->datatype->type = rtype;
4649 sRef_storeState (e->sref);
4655 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4656 ctype ct, /*@only@*/ fileloc loc)
4658 uentry e = uentry_alloc ();
4660 /* e->shallowCopy = FALSE; */
4664 e->sref = sRef_makeUnknown ();
4665 e->storageclass = SCNONE;
4667 if (fileloc_isSpec (loc))
4669 e->whereSpecified = loc;
4670 e->whereDeclared = fileloc_undefined;
4674 e->whereDeclared = loc;
4675 e->whereSpecified = fileloc_undefined;
4678 e->whereDefined = fileloc_undefined;
4680 e->isPrivate = FALSE;
4681 e->hasNameError = FALSE;
4685 e->uses = filelocList_new ();
4686 e->warn = warnClause_undefined; /*@i452@*/
4688 e->info = (uinfo) dmalloc (sizeof (*e->info));
4689 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4690 e->info->iter->access = access;
4691 e->info->iter->mods = sRefSet_undefined;
4692 e->info->iter->globs = globSet_undefined;
4694 sRef_storeState (e->sref);
4699 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4700 /*@only@*/ fileloc loc)
4702 uentry e = uentry_alloc ();
4704 /* e->shallowCopy = FALSE; */
4705 e->ukind = KENDITER;
4706 e->storageclass = SCNONE;
4708 e->utype = ctype_unknown;
4709 e->sref = sRef_makeUnknown ();
4711 if (fileloc_isSpec (loc))
4713 e->whereSpecified = loc;
4714 e->whereDeclared = fileloc_undefined;
4718 e->whereDeclared = loc;
4719 e->whereSpecified = fileloc_undefined;
4722 e->whereDefined = fileloc_undefined;
4724 e->isPrivate = FALSE;
4725 e->hasNameError = FALSE;
4729 e->uses = filelocList_new ();
4730 e->warn = warnClause_undefined; /*@i452@*/
4732 e->info = (uinfo) dmalloc (sizeof (*e->info));
4733 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4734 e->info->enditer->access = access;
4735 sRef_storeState (e->sref);
4740 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4748 uentry_undump (ekind kind, fileloc loc, char **s)
4752 DPRINTF (("Uentry undump: %s", *s));
4756 reader_checkChar (s, '!');
4757 reader_checkChar (s, '.');
4758 ue = uentry_makeElipsisMarker ();
4762 ctype ct = ctype_undump (s);
4776 reader_checkChar (s, '|');
4778 if (reader_optCheckChar (s, '@'))
4780 tkind = vkind_fromInt (reader_getInt (s));
4781 reader_checkChar (s, '|');
4788 if (reader_optCheckChar (s, '$'))
4790 defstate = SS_UNKNOWN;
4791 isnull = NS_UNKNOWN;
4792 aliased = AK_IMPTEMP;
4794 checked = CH_UNKNOWN;
4796 else if (reader_optCheckChar (s, '&'))
4798 defstate = SS_DEFINED;
4799 isnull = NS_UNKNOWN;
4800 aliased = AK_IMPTEMP;
4802 checked = CH_UNKNOWN;
4804 else if (reader_optCheckChar (s, '^'))
4806 defstate = SS_UNKNOWN;
4807 isnull = NS_UNKNOWN;
4808 aliased = AK_IMPTEMP;
4810 checked = CH_UNKNOWN;
4814 defstate = sstate_fromInt (reader_getInt (s));
4815 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4816 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4818 if (reader_optCheckChar (s, '&'))
4821 checked = CH_UNKNOWN;
4825 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4826 advanceField (s); checked = (chkind) (reader_getInt (s));
4831 name = reader_getStringWord (s);
4833 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4835 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4836 isnull, aliased, exp,
4837 checked, fileloc_copy (loc));
4850 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4851 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4852 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4853 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4854 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4855 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4856 advanceField (s); rtype = ctype_undump (s);
4858 name = reader_getStringWord (s);
4859 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4860 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4861 aliased, exp, defstate, isnull,
4862 fileloc_copy (loc));
4879 stateClauseList specclauses = stateClauseList_undefined;
4880 warnClause warnclause = warnClause_undefined;
4882 if (reader_optCheckChar (s, '$'))
4884 defstate = SS_DEFINED;
4885 isnull = NS_UNKNOWN;
4886 exitCode = XK_UNKNOWN;
4888 nullPred = qual_createUnknown ();
4892 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4893 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4894 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4895 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4896 advanceField (s); nullPred = qual_undump (s);
4899 if (reader_optCheckChar (s, '$'))
4902 globs = globSet_undefined;
4904 mods = sRefSet_undefined;
4906 else if (reader_optCheckChar (s, '^'))
4909 globs = globSet_undefined;
4911 mods = sRefSet_undefined;
4915 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4916 advanceField (s); globs = globSet_undump (s);
4917 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4918 advanceField (s); mods = sRefSet_undump (s);
4921 if (reader_optCheckChar (s, '$'))
4928 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4929 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4932 advanceField (s); access = typeIdSet_undump (s);
4935 ** Optional clauses: Start with @<code>:
4938 while (reader_optCheckChar (s, '@'))
4940 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4942 reader_checkChar (s, ':');
4943 warnclause = warnClause_undump (s);
4945 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4947 reader_checkChar (s, ':');
4948 specclauses = stateClauseList_undump (s);
4956 advanceName (s); name = reader_getStringWord (s);
4958 ue = uentry_makeFunctionBase (name, ct, access,
4961 ak, exp, defstate, isnull,
4962 exitCode, specc, nullPred,
4965 fileloc_copy (loc));
4966 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4973 advanceField (s); access = typeIdSet_undump (s);
4974 advanceName (s); name = reader_getStringWord (s);
4976 ue = uentry_makeIterBase (name, access, ct,
4977 fileloc_copy (loc));
4984 advanceField (s); access = typeIdSet_undump (s);
4985 advanceName (s); name = reader_getStringWord (s);
4987 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4997 if (reader_optCheckChar (s, '$'))
4999 val = multiVal_undefined;
5000 access = typeIdSet_undefined;
5001 nullstate = NS_UNKNOWN;
5005 advanceField (s); val = multiVal_undump (s);
5006 advanceField (s); access = typeIdSet_undump (s);
5007 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5010 advanceName (s); name = reader_getStringWord (s);
5012 ue = uentry_makeConstantBase (name, ct, access,
5013 nullstate, fileloc_copy (loc), val);
5022 advanceField (s); rtype = ctype_undump (s);
5023 advanceName (s); name = reader_getStringWord (s);
5024 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5028 llcontbuglit ("uentry_undump: invalid");
5029 ue = uentry_undefined;
5032 llcontbuglit ("uentry_undump: elips marker");
5033 ue = uentry_undefined;
5042 uentry_dump (uentry v)
5044 return (uentry_dumpAux (v, FALSE));
5048 uentry_dumpParam (uentry v)
5050 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5051 ("dump: %s", uentry_unparseFull (v)));
5053 return (uentry_dumpAux (v, TRUE));
5057 uentry_dumpAux (uentry v, bool isParam)
5059 llassert (uentry_isValid (v));
5060 llassert (!uentry_isGlobalMarker (v));
5062 DPRINTF (("Dump uentry: [%p]", v));
5063 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5068 llcontbuglit ("uentry_dump: invalid entry");
5069 return cstring_undefined;
5071 return (message ("!."));
5075 vkind vk = v->info->var->kind;
5076 sstate dss = sRef_getDefState (v->sref);
5077 nstate nst = sRef_getNullState (v->sref);
5078 alkind alk = sRef_getAliasKind (v->sref);
5079 exkind exk = sRef_getExKind (v->sref);
5080 chkind chk = v->info->var->checked;
5082 DPRINTF (("Dumping var"));
5084 if (dss == SS_UNKNOWN
5085 && nst == NS_UNKNOWN
5086 && alk == AK_IMPTEMP
5087 && exk == XO_UNKNOWN
5088 && chk == CH_UNKNOWN)
5090 sdump = cstring_makeLiteral ("$");
5092 else if (dss == SS_DEFINED
5093 && nst == NS_UNKNOWN
5094 && alk == AK_IMPTEMP
5095 && exk == XO_UNKNOWN
5096 && chk == CH_UNKNOWN)
5098 sdump = cstring_makeLiteral ("&");
5100 else if (dss == SS_UNKNOWN
5101 && nst == NS_UNKNOWN
5102 && alk == AK_UNKNOWN
5103 && exk == XO_UNKNOWN
5104 && chk == CH_UNKNOWN)
5106 sdump = cstring_makeLiteral ("^");
5108 else if (exk == XO_UNKNOWN
5109 && chk == CH_UNKNOWN)
5111 sdump = message ("%d@%d@%d&",
5118 sdump = message ("%d@%d@%d@%d@%d",
5129 return (message ("%q|@%d|%q#%s",
5130 ctype_dump (v->utype),
5133 isParam ? cstring_undefined : v->uname));
5137 return (message ("%q|%q#%s",
5138 ctype_dump (v->utype),
5140 isParam ? cstring_undefined : v->uname));
5146 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5148 exkind_unparse (sRef_getExKind (v->sref)),
5149 ctype_unparse (v->utype), (int) v->utype));
5152 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5153 ctype_dump (v->utype),
5154 ynm_unparseCode (v->info->datatype->abs),
5155 ynm_unparseCode (v->info->datatype->mut),
5156 (int) sRef_getDefState (v->sref),
5157 (int) sRef_getNullState (v->sref),
5158 (int) sRef_getAliasKind (v->sref),
5159 (int) sRef_getExKind (v->sref),
5160 ctype_dump (v->info->datatype->type),
5164 cstring sdump, gdump, adump, xdump;
5165 alkind alk = sRef_getAliasKind (v->sref);
5166 exkind exk = sRef_getExKind (v->sref);
5168 if (sRef_getDefState (v->sref) == SS_DEFINED
5169 && !nstate_isKnown (sRef_getNullState (v->sref))
5170 && !exitkind_isKnown (v->info->fcn->exitCode)
5171 && v->info->fcn->specialCode == SPC_NONE
5172 && qual_isUnknown (v->info->fcn->nullPred))
5174 sdump = cstring_makeLiteral ("$");
5178 sdump = message ("@%d@%d@%d@%d@%x",
5179 (int) sRef_getDefState (v->sref),
5180 (int) sRef_getNullState (v->sref),
5181 (int) v->info->fcn->exitCode,
5182 (int) v->info->fcn->specialCode,
5183 qual_dump (v->info->fcn->nullPred));
5186 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5188 gdump = cstring_makeLiteral ("$");
5190 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5191 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5193 gdump = cstring_makeLiteral ("^");
5197 gdump = message ("@%s@%q@%s@%q",
5198 bool_dump (uentry_hasGlobs (v)),
5199 globSet_dump (uentry_getGlobs (v)),
5200 bool_dump (uentry_hasMods (v)),
5201 sRefSet_dump (uentry_getMods (v)));
5204 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5206 adump = cstring_makeLiteral ("$");
5210 adump = message ("@%d@%d", (int) alk, (int) exk);
5213 xdump = cstring_undefined;
5215 if (uentry_hasWarning (v))
5217 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5220 if (uentry_hasStateClauseList (v))
5222 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5225 return (message ("%q%q%q%q@%q%q#%s",
5226 ctype_dump (v->utype),
5230 typeIdSet_dump (uentry_accessType (v)),
5235 return (message ("%q@%q#%s",
5236 ctype_dump (v->utype),
5237 typeIdSet_dump (v->info->iter->access),
5240 return (message ("%q@%q#%s",
5241 ctype_dump (v->utype),
5242 typeIdSet_dump (uentry_accessType (v)),
5249 if (multiVal_isUnknown (uentry_getConstantValue (v))
5250 && typeIdSet_isEmpty (uentry_accessType (v))
5251 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5253 sdump = cstring_makeLiteral ("$");
5257 sdump = message ("@%q@%q@%d",
5258 multiVal_dump (uentry_getConstantValue (v)),
5259 typeIdSet_dump (uentry_accessType (v)),
5260 (int) sRef_getNullState (v->sref));
5263 return (message ("%q%q#%s",
5264 ctype_dump (v->utype),
5271 return (message ("%q@%q#%s",
5272 ctype_dump (v->utype),
5273 ctype_dump (v->info->datatype->type), v->uname));
5280 uentry_unparseAbbrev (uentry v)
5282 if (!uentry_isVariable (v))
5284 llcontbuglit ("uentry_unparseAbbrev: not variable");
5285 return uentry_unparse (v);
5288 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5292 uentry_unparse (uentry v)
5296 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5297 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5299 st = uentry_getName (v);
5301 if (cstring_isDefined (st))
5303 return (ctype_unparseDeclaration (v->utype, st));
5308 return (cstring_copy (ctype_unparse (v->utype)));
5313 uentry_unparseFull (uentry v)
5315 if (uentry_isUndefined (v))
5317 return (cstring_makeLiteral ("<undefined>"));
5323 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5324 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5325 ctype_unparse (v->utype),
5326 fileloc_unparse (uentry_whereSpecified (v)),
5327 fileloc_unparse (uentry_whereDeclared (v)),
5328 fileloc_unparse (uentry_whereDefined (v)));
5330 DPRINTF (("uentry: %s", res));
5332 if (uentry_isDatatype (v))
5334 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5337 (ctype_isDefined (v->info->datatype->type)
5338 ? v->info->datatype->type : ctype_unknown),
5339 ynm_unparse (v->info->datatype->mut),
5340 ynm_unparse (v->info->datatype->abs),
5341 sRef_unparseState (v->sref));
5343 else if (uentry_isFunction (v))
5345 res = message ("%q / sref: %q / mods: %q / "
5346 "globs: %q / clauses: %q / pre: %q / post: %q",
5348 sRef_unparseFull (v->sref),
5349 sRefSet_unparse (v->info->fcn->mods),
5350 globSet_unparse (v->info->fcn->globs),
5351 stateClauseList_unparse (v->info->fcn->specclauses),
5352 functionConstraint_unparse (v->info->fcn->preconditions),
5353 functionConstraint_unparse (v->info->fcn->postconditions));
5355 else if (uentry_isIter (v))
5357 res = message ("%q / sref: %q",
5359 sRef_unparseFull (v->sref));
5361 else if (uentry_isVariable (v))
5363 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5365 sRef_unparseFull (v->sref),
5366 (int) v->info->var->kind,
5367 (int) v->info->var->defstate,
5368 (int) v->info->var->nullstate,
5370 DPRINTF (("sref: [%p]", v->sref));
5371 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5372 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5374 else if (uentry_isConstant (v))
5376 res = message ("%q = %q",
5377 res, multiVal_unparse (uentry_getConstantValue (v)));
5381 res = message ("%q :: %q", res, uentry_unparse (v));
5388 bool uentry_hasAccessType (uentry e)
5390 if (uentry_isValid (e))
5395 return (!typeIdSet_isEmpty (e->info->iter->access));
5397 return (!typeIdSet_isEmpty (e->info->enditer->access));
5399 return (!typeIdSet_isEmpty (e->info->fcn->access));
5402 return (!typeIdSet_isEmpty (e->info->uconst->access));
5411 typeIdSet uentry_accessType (uentry e)
5413 if (uentry_isValid (e))
5418 return (e->info->iter->access);
5420 return (e->info->enditer->access);
5422 return (e->info->fcn->access);
5425 return (e->info->uconst->access);
5431 return typeIdSet_undefined;
5435 uentry_isVariable (uentry e)
5437 return (uentry_isVar (e));
5441 uentry_isSpecified (uentry e)
5443 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5447 uentry_isReallySpecified (uentry e)
5449 return (uentry_isValid (e)
5450 && fileloc_isRealSpec (e->whereSpecified));
5454 uentry_isVar (uentry e)
5456 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5460 uentry_isFakeTag (uentry e)
5462 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5466 uentry_isDatatype (uentry e)
5468 return (!uentry_isUndefined (e) &&
5469 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5470 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5474 uentry_setAbstract (uentry e)
5478 llassert (uentry_isDatatype (e)
5479 && (ynm_isMaybe (e->info->datatype->abs)));
5481 oldid = ctype_typeId (e->info->datatype->type);
5482 e->info->datatype->abs = YES;
5483 e->info->datatype->type = ctype_createAbstract (oldid);
5487 uentry_setConcrete (uentry e)
5489 llassert (uentry_isDatatype (e)
5490 && (ynm_isMaybe (e->info->datatype->abs)));
5492 e->info->datatype->abs = NO;
5496 uentry_isAbstractDatatype (uentry e)
5498 return (uentry_isDatatype (e)
5499 && (ynm_isOn (e->info->datatype->abs)));
5503 uentry_isMaybeAbstract (uentry e)
5505 return (uentry_isDatatype (e)
5506 && (ynm_isMaybe (e->info->datatype->abs)));
5510 uentry_isMutableDatatype (uentry e)
5512 bool res = uentry_isDatatype (e)
5513 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5519 uentry_isRefCountedDatatype (uentry e)
5521 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5525 uentry_isParam (uentry u)
5527 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5528 || u->info->var->kind == VKYIELDPARAM));
5532 uentry_isExpandedMacro (uentry u)
5534 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5538 uentry_isSefParam (uentry u)
5540 return (uentry_isVariable (u)
5541 && (u->info->var->kind == VKSEFPARAM
5542 || u->info->var->kind == VKREFSEFPARAM
5543 || u->info->var->kind == VKSEFRETPARAM
5544 || u->info->var->kind == VKREFSEFRETPARAM));
5548 uentry_isRefParam (uentry u)
5550 return (uentry_isVariable (u)
5551 && (u->info->var->kind == VKREFPARAM
5552 || u->info->var->kind == VKREFYIELDPARAM
5553 || u->info->var->kind == VKREFSEFPARAM
5554 || u->info->var->kind == VKREFSEFRETPARAM));
5558 uentry_isAnyParam (uentry u)
5560 return (uentry_isVariable (u)
5561 && ((u->info->var->kind == VKPARAM)
5562 || (u->info->var->kind == VKSEFPARAM)
5563 || (u->info->var->kind == VKYIELDPARAM)
5564 || (u->info->var->kind == VKRETPARAM)
5565 || (u->info->var->kind == VKSEFRETPARAM)));
5569 uentry_getDefState (uentry u)
5571 if (uentry_isValid (u))
5573 return (sRef_getDefState (u->sref));
5577 return (SS_UNKNOWN);
5582 uentry_isOut (uentry u)
5584 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5585 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5589 uentry_isPartial (uentry u)
5591 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5592 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5596 uentry_isStateSpecial (uentry u)
5598 return ((uentry_isVariable (u)
5599 && (u->info->var->defstate == SS_SPECIAL))
5600 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5603 exitkind uentry_getExitCode (uentry ue)
5605 if (uentry_isFunction (ue))
5607 return ue->info->fcn->exitCode;
5615 qual uentry_nullPred (uentry u)
5617 llassert (uentry_isRealFunction (u));
5619 if (uentry_isFunction (u))
5621 return (u->info->fcn->nullPred);
5625 return qual_createUnknown ();
5630 ** Note for variables, this is checking the declared state, not the current state.
5634 uentry_possiblyNull (uentry u)
5636 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5637 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5641 uentry_getAliasKind (uentry u)
5643 if (uentry_isValid (u))
5645 return (sRef_getAliasKind (uentry_getSref (u)));
5654 uentry_getExpKind (uentry u)
5656 if (uentry_isValid (u))
5658 return (sRef_getExKind (uentry_getSref (u)));
5667 uentry_isIter (uentry e)
5669 return (!uentry_isUndefined (e) && e->ukind == KITER);
5673 uentry_isEndIter (uentry e)
5675 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5679 uentry_isRealFunction (uentry e)
5681 return (uentry_isFunction (e) ||
5682 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5686 uentry_hasName (uentry e)
5688 if (uentry_isValid (e))
5690 cstring s = e->uname;
5692 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5693 || uentry_isFakeTag (e)));
5702 ** Returns true for fake tags.
5703 ** This is used for dumping the library
5706 bool uentry_hasRealName (uentry e)
5708 return (uentry_isValid (e)
5709 && cstring_isNonEmpty (e->uname)
5710 && !uentry_isGlobalMarker (e));
5714 /*@observer@*/ globSet
5715 uentry_getGlobs (uentry l)
5717 if (uentry_isInvalid (l))
5719 return globSet_undefined;
5722 if (l->ukind != KFCN)
5724 if (l->ukind != KITER && l->ukind != KENDITER)
5726 if (l->ukind == KVAR)
5728 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5730 ekind_unparse (l->ukind)));
5734 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5736 ekind_unparse (l->ukind)));
5739 return globSet_undefined;
5742 return l->info->fcn->globs;
5745 /*@observer@*/ sRefSet
5746 uentry_getMods (uentry l)
5748 llassert (uentry_isValid (l));
5750 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5752 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5753 return sRefSet_undefined;
5756 return l->info->fcn->mods;
5760 uentry_getKind (uentry e)
5762 llassert (uentry_isValid (e));
5767 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5769 llassert (uentry_isEitherConstant (e));
5770 return (sRef_getValue (e->sref));
5773 /*@observer@*/ uentryList
5774 uentry_getParams (uentry l)
5776 if (uentry_isInvalid (l)) return uentryList_undefined;
5783 ctype ct = l->utype;
5785 if (ctype_isFunction (ct))
5787 return (ctype_argsFunction (ct));
5791 return uentryList_undefined;
5796 ctype ct = l->utype;
5798 llassert (ctype_isFunction (ct));
5799 return (ctype_argsFunction (ct));
5806 /*@observer@*/ cstring
5807 uentry_rawName (uentry e)
5809 if (uentry_isValid (e))
5815 return cstring_undefined;
5820 uentry_getOptName (uentry e)
5822 cstring s = uentry_getName (e);
5824 if (cstring_isDefined (s))
5826 s = cstring_appendChar (s, ' ');
5833 uentry_getName (uentry e)
5835 cstring ret = cstring_undefined;
5837 if (uentry_isValid (e))
5839 if (uentry_isAnyTag (e))
5841 ret = fixTagName (e->uname);
5843 else if (uentry_isAnyParam (e))
5845 ret = cstring_copy (fixParamName (e->uname));
5849 ret = cstring_copy (e->uname);
5856 cstring uentry_observeRealName (uentry e)
5858 cstring ret = cstring_undefined;
5860 if (uentry_isValid (e))
5862 if (uentry_isAnyTag (e))
5864 if (isFakeTag (e->uname))
5866 ret = cstring_undefined;
5870 ret = plainTagName (e->uname);
5873 else if (uentry_isAnyParam (e))
5875 ret = fixParamName (e->uname);
5886 cstring uentry_getRealName (uentry e)
5888 if (uentry_isValid (e))
5890 if (uentry_isAnyTag (e))
5892 return (cstring_undefined);
5899 return cstring_undefined;
5902 ctype uentry_getType (uentry e)
5904 if (uentry_isValid (e))
5910 return ctype_unknown;
5914 fileloc uentry_whereLast (uentry e)
5918 if (uentry_isInvalid (e))
5920 return fileloc_undefined;
5923 loc = e->whereDefined;
5925 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5930 loc = uentry_whereDeclared (e);
5932 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5937 loc = uentry_whereSpecified (e);
5941 fileloc uentry_whereEither (uentry e)
5943 if (uentry_isInvalid (e)) return fileloc_undefined;
5945 if (fileloc_isDefined (e->whereDefined)
5946 && !fileloc_isExternal (e->whereDefined))
5948 return e->whereDefined;
5950 else if (fileloc_isDefined (e->whereDeclared))
5952 return e->whereDeclared;
5956 return e->whereSpecified;
5960 fileloc uentry_whereSpecified (uentry e)
5962 if (uentry_isInvalid (e)) return fileloc_undefined;
5964 return (e->whereSpecified);
5967 fileloc uentry_whereDefined (uentry e)
5969 if (uentry_isInvalid (e)) return fileloc_undefined;
5971 return (e->whereDefined);
5974 fileloc uentry_whereDeclared (uentry e)
5976 if (uentry_isInvalid (e)) return fileloc_undefined;
5978 return (e->whereDeclared);
5981 /*@observer@*/ fileloc
5982 uentry_whereEarliest (uentry e)
5984 if (uentry_isInvalid (e)) return fileloc_undefined;
5986 if (fileloc_isDefined (e->whereSpecified))
5988 return (e->whereSpecified);
5990 else if (fileloc_isDefined (e->whereDeclared))
5992 return (e->whereDeclared);
5996 return e->whereDefined;
6001 uentry_setFunctionDefined (uentry e, fileloc loc)
6003 if (uentry_isValid (e))
6005 llassert (uentry_isFunction (e));
6007 if (fileloc_isUndefined (e->whereDeclared))
6009 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6012 if (!fileloc_isDefined (e->whereDefined))
6014 e->whereDefined = fileloc_update (e->whereDefined, loc);
6020 uentry_setDeclDef (uentry e, fileloc f)
6022 uentry_setDeclared (e, f);
6024 if (!uentry_isFunction (e)
6025 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6027 uentry_setDefined (e, f);
6032 uentry_setDeclaredForce (uentry e, fileloc f)
6034 llassert (uentry_isValid (e));
6035 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6039 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6041 llassert (uentry_isValid (e));
6042 fileloc_free (e->whereDeclared);
6043 e->whereDeclared = f;
6047 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6051 llassert (uentry_isValid (e));
6052 oldloc = e->whereDeclared;
6054 if (fileloc_isDefined (oldloc))
6056 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6058 e->whereDeclared = f;
6059 fileloc_free (oldloc);
6068 e->whereDeclared = f;
6069 fileloc_free (oldloc);
6074 uentry_setDeclared (uentry e, fileloc f)
6078 llassert (uentry_isValid (e));
6079 oldloc = e->whereDeclared;
6081 if (fileloc_isDefined (oldloc))
6083 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6085 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6094 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6099 uentry_clearDefined (uentry e)
6101 if (uentry_isValid (e))
6103 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6108 uentry_setDefined (uentry e, fileloc f)
6112 llassert (uentry_isValid (e));
6113 oldloc = e->whereDefined;
6115 if (fileloc_isDefined (oldloc))
6117 if (fileloc_isLib (oldloc)
6118 || fileloc_isImport (oldloc)
6119 || fileloc_isBuiltin (oldloc)
6120 || fileloc_isPreproc (oldloc))
6122 e->whereDefined = fileloc_update (e->whereDefined, f);
6126 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6132 if (optgenerror (FLG_REDEF,
6133 message ("%s %q redefined",
6134 ekind_capName (e->ukind),
6135 uentry_getName (e)),
6138 llgenindentmsg (message ("Previous definition of %q",
6139 uentry_getName (e)),
6147 e->whereDefined = fileloc_update (e->whereDefined, f);
6152 uentry_isCodeDefined (uentry e)
6154 llassert (uentry_isValid (e));
6156 return (fileloc_isDefined (e->whereDefined));
6160 uentry_isDeclared (uentry e)
6162 if (uentry_isValid (e))
6164 return (fileloc_isDefined (e->whereDeclared));
6170 sRef uentry_getSref (uentry e)
6172 /* not true, used for functions too (but shouldn't be? */
6173 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6175 if (uentry_isInvalid (e)) return sRef_undefined;
6180 sRef uentry_getOrigSref (uentry e)
6182 /*@i523*/ /* evans 2001-09-09 - need to fix this
6183 if (uentry_isValid (e))
6185 if (uentry_isVariable (e))
6187 return e->info->var->origsref;
6191 sRef sr = sRef_copy (uentry_getSref (e));
6193 sRef_resetState (sr);
6194 sRef_clearDerived (sr);
6200 return sRef_undefined;
6204 if (uentry_isValid (e))
6206 sRef sr = sRef_copy (uentry_getSref (e));
6208 sRef_resetState (sr);
6209 sRef_clearDerived (sr);
6211 if (uentry_isVariable (e))
6213 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6214 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6221 return sRef_undefined;
6226 ** requires: uentry e is not in a hashed symbol table
6230 uentry_setName (uentry e, /*@only@*/ cstring n)
6232 llassert (uentry_isValid (e));
6234 cstring_free (e->uname);
6239 uentry_setType (uentry e, ctype t)
6241 if (uentry_isValid (e))
6244 sRef_setType (e->sref, t);
6249 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6252 ctype rettype = ctype_unknown;
6254 llassert (uentry_isValid (ue));
6256 uentry_convertVarFunction (ue);
6257 llassert (uentry_isFunction (ue));
6259 rct = ctype_realType (ue->utype);
6261 if (ctype_isFunction (rct))
6263 rettype = ctype_getReturnType (rct);
6266 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6270 uentry_setRefParam (uentry e)
6272 if (!uentry_isVar (e))
6274 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6278 if (e->info->var->kind == VKSEFPARAM)
6280 e->info->var->kind = VKREFSEFPARAM;
6282 else if (e->info->var->kind == VKSEFRETPARAM)
6284 e->info->var->kind = VKREFSEFRETPARAM;
6286 else if (e->info->var->kind == VKYIELDPARAM)
6288 e->info->var->kind = VKREFYIELDPARAM;
6292 e->info->var->kind = VKREFPARAM;
6298 uentry_setParam (uentry e)
6300 if (!uentry_isVar (e))
6302 if (uentry_isElipsisMarker (e))
6308 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6315 if (e->info->var->kind == VKYIELDPARAM
6316 || e->info->var->kind == VKSEFPARAM
6317 || e->info->var->kind == VKSEFRETPARAM)
6323 e->info->var->kind = VKPARAM;
6327 e->uname = makeParam (e->uname);
6328 cstring_free (oldname);
6333 uentry_setSref (uentry e, sRef s)
6335 if (uentry_isValid (e))
6337 if (sRef_isValid (e->sref))
6339 sRef_mergeStateQuietReverse (e->sref, s);
6343 e->sref = sRef_saveCopy (s);
6349 uentry_getAbstractType (uentry e)
6351 llassert (uentry_isDatatype (e));
6354 ** This assertion removed.
6355 ** Okay to have undefined type, for system types
6357 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6358 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6363 if (ctype_isUndefined (e->info->datatype->type))
6365 return ctype_unknown;
6369 ** Sadly, a kludge...
6372 if (ctype_isUserBool (e->info->datatype->type)) {
6376 return e->info->datatype->type;
6379 ctype uentry_getRealType (uentry e)
6382 typeId uid = USYMIDINVALID;
6384 if (uentry_isInvalid (e))
6386 return ctype_unknown;
6389 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6391 if (uentry_isAnyTag (e))
6396 if (uentry_isAbstractType (e))
6398 ct = uentry_getAbstractType (e);
6400 if (ctype_isManifestBool (ct)) {
6404 llassert (ctype_isUA (ct));
6406 uid = ctype_typeId (ct);
6408 if (!context_hasAccess (uid))
6414 ct = uentry_getType (e);
6416 /* if (ctype_isUserBool (ct)) return ct; */
6418 if (ctype_isManifestBool (ct)) {
6422 if (ctype_isUA (ct))
6424 usymId iid = ctype_typeId (ct);
6426 if (usymId_equal (iid, uid))
6428 llcontbug (message ("uentry_getRealType: recursive type! %s",
6429 ctype_unparse (ct)));
6434 /* evs 2000-07-25: possible infinite recursion ? */
6435 uentry ue2 = usymtab_getTypeEntry (iid);
6439 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6440 return ctype_unknown;
6443 return uentry_getRealType (ue2);
6452 ctype uentry_getForceRealType (uentry e)
6455 typeId uid = USYMIDINVALID;
6457 if (uentry_isInvalid (e))
6459 return ctype_unknown;
6462 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6464 if (uentry_isAnyTag (e))
6469 if (uentry_isAbstractType (e))
6471 ct = uentry_getAbstractType (e);
6472 llassert (ctype_isUA (ct));
6474 uid = ctype_typeId (ct);
6475 /* no check for access! */
6478 ct = uentry_getType (e);
6480 /* evs 2000-07-25 */
6481 /* if (ctype_isUserBool (ct)) return ct; */
6483 if (ctype_isManifestBool (ct)) {
6487 if (ctype_isUA (ct))
6489 usymId iid = ctype_typeId (ct);
6491 if (usymId_equal (iid, uid))
6493 llcontbug (message ("uentry_getRealType: recursive type! %s",
6494 ctype_unparse (ct)));
6499 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6508 uentry uentry_nameCopy (cstring name, uentry e)
6510 uentry enew = uentry_alloc ();
6512 llassert (uentry_isValid (e));
6514 /* enew->shallowCopy = FALSE; */
6515 enew->ukind = e->ukind;
6517 enew->utype = e->utype;
6518 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6519 enew->whereDefined = fileloc_copy (e->whereDefined);
6520 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6521 enew->sref = sRef_copy (e->sref);
6522 enew->used = e->used;
6524 enew->isPrivate = e->isPrivate;
6525 enew->hasNameError = FALSE;
6527 enew->uses = filelocList_new ();
6528 enew->warn = warnClause_undefined;
6530 enew->storageclass = e->storageclass;
6531 enew->info = uinfo_copy (e->info, e->ukind);
6537 uentry_setDatatype (uentry e, usymId uid)
6539 llassert (uentry_isDatatype (e));
6541 if (uentry_isAbstractType (e))
6543 e->info->datatype->type = ctype_createAbstract (uid);
6547 e->info->datatype->type = ctype_createUser (uid);
6552 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6553 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6556 llassert (uentry_isValid (e));
6558 if (fileloc_isSpec (f) || fileloc_isImport (f))
6560 e->whereSpecified = f;
6561 e->whereDeclared = fileloc_undefined;
6562 e->whereDefined = fileloc_undefined;
6566 e->whereSpecified = fileloc_undefined;
6567 e->whereDeclared = f;
6568 e->whereDefined = fileloc_undefined;
6571 llassert (fileloc_storable (f));
6575 ucinfo_free (/*@only@*/ ucinfo u)
6581 uvinfo_free (/*@only@*/ uvinfo u)
6583 /*drl7x added 6/29/01 */
6584 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6589 udinfo_free (/*@only@*/ udinfo u)
6595 ufinfo_free (/*@only@*/ ufinfo u)
6597 globSet_free (u->globs);
6598 sRefSet_free (u->mods);
6599 stateClauseList_free (u->specclauses);
6604 uiinfo_free (/*@only@*/ uiinfo u)
6610 ueinfo_free (/*@only@*/ ueinfo u)
6615 static /*@only@*/ ucinfo
6616 ucinfo_copy (ucinfo u)
6618 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6619 ret->access = u->access;
6620 ret->macro = u->macro;
6624 static /*@only@*/ uvinfo
6625 uvinfo_copy (uvinfo u)
6627 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6629 ret->kind = u->kind;
6630 ret->nullstate = u->nullstate;
6631 ret->defstate = u->defstate;
6632 ret->checked = u->checked;
6634 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6636 /* drl added 07-02-001 */
6637 /* copy null terminated information */
6639 if (u->bufinfo != NULL)
6641 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6642 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6643 ret->bufinfo->size = u->bufinfo->size;
6644 ret->bufinfo->len = u->bufinfo->len;
6649 ret->bufinfo = NULL;
6655 static /*@only@*/ udinfo
6656 udinfo_copy (udinfo u)
6658 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6662 ret->type = u->type;
6667 static /*@only@*/ ufinfo
6668 ufinfo_copy (ufinfo u)
6670 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6672 ret->hasGlobs = u->hasGlobs;
6673 ret->hasMods = u->hasMods;
6674 ret->exitCode = u->exitCode;
6675 ret->specialCode = u->specialCode;
6676 ret->nullPred = u->nullPred;
6677 ret->access = u->access;
6678 ret->globs = globSet_newCopy (u->globs);
6679 ret->mods = sRefSet_newCopy (u->mods);
6680 ret->defparams = u->defparams;
6681 ret->specclauses = stateClauseList_copy (u->specclauses);
6683 ret->preconditions = functionConstraint_copy (u->preconditions);
6684 ret->postconditions = functionConstraint_copy (u->postconditions);
6689 static /*@only@*/ uiinfo
6690 uiinfo_copy (uiinfo u)
6692 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6694 ret->access = u->access;
6695 ret->globs = globSet_newCopy (u->globs);
6696 ret->mods = sRefSet_newCopy (u->mods);
6701 static /*@only@*/ ueinfo
6702 ueinfo_copy (ueinfo u)
6704 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6706 ret->access = u->access;
6711 uinfo_free (uinfo u, ekind kind)
6716 case KCONST: ucinfo_free (u->uconst); break;
6717 case KVAR: uvinfo_free (u->var); break;
6721 case KDATATYPE: udinfo_free (u->datatype); break;
6722 case KFCN: ufinfo_free (u->fcn); break;
6723 case KITER: uiinfo_free (u->iter); break;
6724 case KENDITER: ueinfo_free (u->enditer); break;
6725 case KELIPSMARKER: break;
6726 case KINVALID: break;
6732 static /*@only@*/ /*@null@*/ uinfo
6733 uinfo_copy (uinfo u, ekind kind)
6735 if (kind == KELIPSMARKER || kind == KINVALID)
6741 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6746 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6747 case KVAR: ret->var = uvinfo_copy (u->var); break;
6751 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6752 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6753 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6754 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6762 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6764 filelocList_free (e->uses);
6765 cstring_free (e->uname);
6767 uinfo_free (e->info, e->ukind);
6769 fileloc_free (e->whereSpecified);
6770 fileloc_free (e->whereDefined);
6771 fileloc_free (e->whereDeclared);
6773 warnClause_free (e->warn);
6779 extern void uentry_markOwned (/*@owned@*/ uentry u)
6781 sfreeEventually (u);
6785 uentry_free (/*@only@*/ uentry e)
6787 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6789 uentry_reallyFree (e);
6794 ** For uentry's in the global or file scope
6798 uentry_freeComplete (/*@only@*/ uentry e)
6800 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6802 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6803 /*@i@*/ sRef_free (e->sref);
6804 e->sref = sRef_undefined;
6805 uentry_reallyFree (e);
6810 ** requires old->kind != new->kind, old->uname = new->uname
6814 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6816 llassert (uentry_isValid (old));
6817 llassert (uentry_isValid (unew));
6819 if (uentry_isEitherConstant (unew)
6820 && (fileloc_isPreproc (uentry_whereDeclared (old))
6821 || ctype_isUnknown (old->utype))
6822 && !uentry_isSpecified (old))
6830 if (!uentry_isDeclared (old))
6832 if (uentry_isSpecified (old))
6834 if (uentry_isSpecified (unew))
6836 llbuglit ("Respecification!");
6838 else if (uentry_isDeclared (unew))
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);
6861 message ("%s %q inconsistently declared as %s: %t",
6862 ekind_capName (old->ukind),
6863 uentry_getName (unew),
6864 ekind_unparseLong (unew->ukind),
6866 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6868 uentry_showWhereLastKind (old);
6874 llassert (uentry_isDeclared (unew));
6876 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6877 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6881 message ("%s %q inconsistently redeclared as %s",
6882 ekind_capName (old->ukind),
6883 uentry_getName (unew),
6884 ekind_unparseLong (unew->ukind)),
6885 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6887 uentry_showWhereLastKind (old);
6893 uentry_updateInto (old, unew);
6897 ** def is the definition of spec, modifies spec
6899 ** reports any inconsistencies
6900 ** returns the summary of all available information
6901 ** if spec and def are inconsistent, def is returned
6905 uentry_showWhereLast (uentry spec)
6907 if (uentry_isValid (spec))
6909 if (fileloc_isDefined (spec->whereDefined)
6910 && !fileloc_isLib (spec->whereDefined)
6911 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6913 llgenindentmsg (message ("Previous definition of %q: %t",
6914 uentry_getName (spec),
6915 uentry_getType (spec)),
6916 uentry_whereDefined (spec));
6918 else if (uentry_isDeclared (spec))
6920 llgenindentmsg (message ("Previous declaration of %q: %t",
6921 uentry_getName (spec),
6922 uentry_getType (spec)),
6923 uentry_whereDeclared (spec));
6925 else if (uentry_isSpecified (spec))
6927 if (uentry_hasName (spec))
6929 llgenindentmsg (message ("Specification of %q: %t",
6930 uentry_getName (spec),
6931 uentry_getType (spec)),
6932 uentry_whereSpecified (spec));
6936 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6937 uentry_whereSpecified (spec));
6942 /* nothing to show */
6948 uentry_showWhereLastKind (uentry spec)
6950 if (uentry_isValid (spec))
6952 if (fileloc_isDefined (spec->whereDefined)
6953 && !fileloc_isLib (spec->whereDefined)
6954 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6956 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6957 uentry_getName (spec),
6958 ekind_unparseLong (spec->ukind),
6959 uentry_getType (spec)),
6960 uentry_whereDefined (spec));
6962 else if (uentry_isDeclared (spec))
6964 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6965 uentry_getName (spec),
6966 ekind_unparseLong (spec->ukind),
6967 uentry_getType (spec)),
6968 uentry_whereDeclared (spec));
6970 else if (uentry_isSpecified (spec))
6972 if (uentry_hasName (spec))
6974 llgenindentmsg (message ("Specification of %q as %s: %t",
6975 uentry_getName (spec),
6976 ekind_unparseLong (spec->ukind),
6977 uentry_getType (spec)),
6978 uentry_whereSpecified (spec));
6982 llgenindentmsg (message ("Specification as %s: %t",
6983 ekind_unparseLong (spec->ukind),
6984 uentry_getType (spec)),
6985 uentry_whereSpecified (spec));
6990 /* nothing to show */
6996 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6998 fileloc loc = uentry_whereDefined (ce);
7000 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7002 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7006 loc = uentry_whereSpecified (ce);
7008 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7010 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7015 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7017 if (uentry_isDeclared (spec))
7019 llgenindentmsg (message ("Previous declaration of %q: %q",
7020 uentry_getName (spec), extra),
7021 uentry_whereDeclared (spec));
7023 else if (uentry_isSpecified (spec))
7025 llgenindentmsg (message ("Specification of %q: %q",
7026 uentry_getName (spec), extra),
7027 uentry_whereSpecified (spec));
7031 cstring_free (extra);
7036 uentry_showWhereDeclared (uentry spec)
7038 if (uentry_isDeclared (spec))
7040 if (uentry_hasName (spec))
7042 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7043 uentry_whereDeclared (spec));
7047 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7050 else if (uentry_isSpecified (spec))
7052 if (uentry_hasName (spec))
7054 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7055 uentry_whereSpecified (spec));
7059 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7064 /* nothing to show */
7070 uentry_showWhereAny (uentry spec)
7072 if (uentry_isDeclared (spec))
7074 if (uentry_hasName (spec))
7076 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7077 uentry_whereDeclared (spec));
7081 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7084 else if (uentry_isSpecified (spec))
7086 if (uentry_hasName (spec))
7088 llgenindentmsg (message ("Specification of %q",
7089 uentry_getName (spec)),
7090 uentry_whereSpecified (spec));
7094 llgenindentmsg (cstring_makeLiteral ("Specification"),
7095 uentry_whereSpecified (spec));
7098 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7100 if (uentry_hasName (spec))
7102 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7103 uentry_whereDefined (spec));
7107 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7112 /* nothing to show */
7117 uentry_showWhereDefined (uentry spec)
7119 if (uentry_isCodeDefined (spec))
7121 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7122 uentry_whereDefined (spec));
7127 uentry_showWhereLastPlain (uentry spec)
7129 if (uentry_isDeclared (spec))
7131 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7132 uentry_whereDeclared (spec));
7134 else if (uentry_isSpecified (spec))
7136 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7137 uentry_whereSpecified (spec));
7145 uentry_showWhereLastVal (uentry spec, cstring val)
7147 if (uentry_isDeclared (spec))
7149 llgenindentmsg (message ("Previous declaration of %q: %s",
7150 uentry_getName (spec), val),
7151 uentry_whereDeclared (spec));
7153 else if (uentry_isSpecified (spec))
7155 llgenindentmsg (message ("Specification of %q: %s",
7156 uentry_getName (spec), val),
7157 uentry_whereSpecified (spec));
7165 uentry_showWhereSpecified (uentry spec)
7167 if (uentry_isSpecified (spec))
7169 if (uentry_hasName (spec))
7171 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7172 uentry_whereSpecified (spec));
7176 llgenindentmsg (cstring_makeLiteral ("Specification"),
7177 uentry_whereSpecified (spec));
7180 else if (uentry_isDeclared (spec))
7182 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7183 uentry_whereDeclared (spec));
7187 /* nothing to show */
7192 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7194 if (uentry_isSpecified (spec))
7196 if (uentry_hasName (spec))
7198 llgenindentmsg (message ("Specification of %q: %q",
7199 uentry_getName (spec), s),
7200 uentry_whereSpecified (spec));
7204 llgenindentmsg (message ("Specification: %q", s),
7205 uentry_whereSpecified (spec));
7208 else if (uentry_isDeclared (spec))
7210 llgenindentmsg (message ("Declaration of %q: %q",
7211 uentry_getName (spec), s),
7212 uentry_whereDeclared (spec));
7216 llgenindentmsg (message ("Previous: %q", s),
7217 uentry_whereLast (spec));
7226 checkStructConformance (uentry old, uentry unew)
7229 uentryList fold, fnew;
7232 ** requires: types of old and new are structs or unions
7235 llassert (uentry_isValid (old));
7236 llassert (uentry_isValid (unew));
7238 oldr = ctype_realType (old->utype);
7239 fold = ctype_getFields (oldr);
7241 newr = ctype_realType (unew->utype);
7242 fnew = ctype_getFields (newr);
7244 if (!uentryList_matchFields (fold, fnew))
7246 if (fileloc_equal (uentry_whereLast (old),
7247 uentry_whereLast (unew)))
7255 message ("%q %q %rdeclared with fields { %q }, %s "
7256 "with fields { %q }",
7257 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7258 uentry_getName (old),
7259 uentry_isDeclared (old),
7260 uentryList_unparseAbbrev (fnew),
7261 uentry_specOrDefName (old),
7262 uentryList_unparseAbbrev (fold)),
7263 uentry_whereDeclared (unew)))
7265 uentry_showWhereLastPlain (old);
7266 uentryList_showFieldDifference (fold, fnew);
7270 old->utype = unew->utype;
7275 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7278 ** requires old and new are enums
7281 ctype rold = ctype_realType (old->utype);
7282 ctype rnew = ctype_realType (unew->utype);
7283 enumNameList eold = ctype_elist (rold);
7284 enumNameList enew = ctype_elist (rnew);
7286 if (!enumNameList_match (eold, enew))
7290 message ("Enum %q declared with members { %q } but "
7291 "specified with members { %q }",
7292 uentry_getName (old),
7293 enumNameList_unparse (enew),
7294 enumNameList_unparse (eold)),
7295 uentry_whereDeclared (unew)))
7297 uentry_showWhereSpecified (old);
7298 old->utype = unew->utype;
7304 ** either oldCurrent or newCurrent may be undefined!
7308 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7309 uentry unew, uentry newCurrent, ctype newType,
7312 bool hasError = FALSE;
7314 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7316 if (uentry_hasName (newCurrent))
7318 hasError = optgenerror
7320 message ("Parameter %d, %q, of function %q has inconsistent type: "
7321 "declared %t, %s %t",
7322 paramno + 1, uentry_getName (newCurrent),
7323 uentry_getName (unew),
7324 newType, uentry_specOrDefName (old), oldType),
7325 uentry_whereDeclared (newCurrent));
7329 hasError = optgenerror
7331 message ("Parameter %d of function %q has inconsistent type: "
7332 "declared %t, %s %t",
7333 paramno + 1, uentry_getName (unew),
7334 newType, uentry_specOrDefName (old), oldType),
7335 uentry_whereDeclared (newCurrent));
7337 DPRINTF (("type: %s / %s",
7338 ctype_unparse (newType),
7339 ctype_unparse (ctype_realType (newType))));
7344 if (uentry_isDeclared (unew))
7346 hasError = optgenerror
7348 message ("Parameter %d of function %s has inconsistent type: "
7349 "declared %t, %s %t",
7350 paramno + 1, unew->uname,
7351 newType, uentry_specOrDefName (old), oldType),
7352 uentry_whereDeclared (unew));
7356 hasError = optgenerror
7358 message ("Parameter %d of function %s has inconsistent type: "
7359 "declared %t, %s %t",
7360 paramno + 1, unew->uname,
7361 newType, uentry_specOrDefName (old), oldType),
7362 uentry_whereDeclared (unew));
7368 DPRINTF (("Here: %s / %s",
7369 uentry_unparseFull (oldCurrent),
7370 uentry_unparseFull (newCurrent)));
7372 if (!uentry_isUndefined (oldCurrent))
7374 if (!uentry_isUndefined (newCurrent)
7375 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7377 uentry_showWhereLast (oldCurrent);
7381 uentry_showWhereLastPlain (old);
7384 uentry_setType (oldCurrent, newType);
7388 uentry_showWhereLastPlain (old);
7394 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7398 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7400 uentry_isDeclared (old),
7401 uentryList_size (uentry_getParams (unew)),
7402 uentry_specOrDefName (old),
7403 uentryList_size (uentry_getParams (old))),
7404 uentry_whereDeclared (unew)))
7406 uentry_showWhereLastPlain (old);
7411 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7415 message ("Function %s inconsistently %rdeclared to return %t",
7417 uentry_isDeclared (old),
7418 ctype_getReturnType (unew->utype)),
7419 uentry_whereDeclared (unew)))
7421 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7425 static cstring paramStorageName (uentry ue)
7427 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7430 static cstring fcnErrName (uentry ue)
7432 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7435 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7437 if (uentry_isVar (ue))
7439 return (checkedName (ue->info->var->checked));
7443 return (cstring_makeLiteralTemp ("<checked invalid>"));
7447 static cstring checkedName (chkind checked)
7451 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7452 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7453 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7454 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7455 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7461 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7466 if (uentry_isVar (unew))
7468 llassert (uentry_isVar (old));
7470 oldState = old->info->var->nullstate;
7471 newState = unew->info->var->nullstate;
7475 oldState = sRef_getNullState (old->sref);
7476 newState = sRef_getNullState (unew->sref);
7479 if (oldState == NS_ABSNULL)
7481 if (uentry_isVar (old))
7483 old->info->var->nullstate = newState;
7486 sRef_mergeNullState (old->sref, newState);
7488 else if (newState == NS_UNKNOWN)
7490 if (completeConform && newState != oldState
7491 && uentry_isReallySpecified (old))
7495 message ("%s %q specified as %s, but declared without %s qualifier",
7496 ekind_capName (unew->ukind),
7497 uentry_getName (unew),
7498 nstate_unparse (oldState),
7499 nstate_unparse (oldState)),
7500 uentry_whereDeclared (unew)))
7502 uentry_showWhereSpecified (old);
7506 if (uentry_isVar (unew))
7508 unew->info->var->nullstate = oldState;
7511 sRef_mergeNullState (unew->sref, oldState);
7513 else if (newState == NS_POSNULL)
7515 if (oldState == NS_MNOTNULL
7516 && (ctype_isUA (unew->utype)
7517 || (uentry_isFunction (unew)
7518 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7520 if (uentry_isVar (unew))
7522 unew->info->var->nullstate = oldState;
7525 sRef_mergeNullState (unew->sref, oldState);
7529 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7530 || oldState == NS_UNKNOWN)
7537 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7539 uentry_ekindName (unew),
7540 uentry_getName (unew),
7541 uentry_isDeclared (old),
7543 uentry_specOrDefName (old),
7544 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7545 uentry_whereDeclared (unew)))
7547 uentry_showWhereSpecified (old);
7552 if (uentry_isVar (old))
7554 old->info->var->nullstate = newState;
7557 sRef_mergeNullState (old->sref, newState);
7560 else if (newState == NS_MNOTNULL)
7562 if (oldState != NS_MNOTNULL)
7568 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7569 "%s without notnull qualifier",
7570 uentry_ekindName (unew),
7571 uentry_getName (unew),
7572 uentry_isDeclared (old),
7574 uentry_specOrDefName (old)),
7575 uentry_whereDeclared (unew)))
7577 uentry_showWhereSpecified (old);
7581 if (uentry_isVar (old))
7583 old->info->var->nullstate = newState;
7586 sRef_mergeNullState (old->sref, newState);
7591 if (uentry_isVar (unew))
7593 unew->info->var->nullstate = oldState;
7596 sRef_mergeNullState (unew->sref, oldState);
7601 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7602 bool mustConform, bool completeConform)
7608 if (uentry_isVar (old) && uentry_isVar (unew))
7610 oldState = old->info->var->defstate;
7611 newState = unew->info->var->defstate;
7616 oldState = sRef_getDefState (old->sref);
7617 newState = sRef_getDefState (unew->sref);
7620 if (newState != oldState
7621 && newState != SS_UNKNOWN
7622 && newState != SS_DEFINED)
7628 message ("%s %q inconsistently %rdeclared %s %s %s, "
7630 uentry_ekindName (unew),
7631 uentry_getName (unew),
7632 uentry_isDeclared (old),
7634 sstate_unparse (newState),
7635 paramStorageName (unew),
7636 uentry_specOrDefName (old),
7638 sstate_unparse (oldState),
7639 paramStorageName (unew)),
7640 uentry_whereDeclared (unew)))
7642 uentry_showWhereSpecified (old);
7646 if (vars) old->info->var->defstate = newState;
7647 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7652 && (newState != oldState) && (oldState != SS_DEFINED)
7653 && uentry_isReallySpecified (old))
7657 message ("%s %q specified as %s, but declared without %s qualifier",
7658 ekind_capName (unew->ukind),
7659 uentry_getName (unew),
7660 sstate_unparse (oldState),
7661 sstate_unparse (oldState)),
7662 uentry_whereDeclared (unew)))
7664 uentry_showWhereSpecified (old);
7668 if (vars) unew->info->var->defstate = oldState;
7669 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7674 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7675 bool mustConform, bool completeConform)
7680 oldKind = sRef_getAliasKind (old->sref);
7681 newKind = sRef_getAliasKind (unew->sref);
7683 if (alkind_isImplicit (newKind)
7684 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7686 if (completeConform && !alkind_equal (newKind, oldKind)
7687 && uentry_isReallySpecified (old))
7691 message ("%s %q specified as %s, but declared without "
7692 "explicit alias qualifier",
7693 ekind_capName (unew->ukind),
7694 uentry_getName (unew),
7695 alkind_unparse (oldKind)),
7696 uentry_whereDeclared (unew)))
7698 uentry_showWhereSpecified (old);
7703 ** This really shouldn't be necessary, but it is!
7704 ** Function params (?) use new here.
7707 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7711 if (alkind_isKnown (newKind))
7713 if (!alkind_equal (oldKind, newKind))
7715 if (alkind_isKnown (oldKind))
7720 message ("%s %q inconsistently %rdeclared %s %s storage, "
7722 uentry_ekindName (unew),
7723 uentry_getName (unew),
7724 uentry_isDeclared (old),
7726 alkind_unparse (newKind),
7727 uentry_specOrDefName (old),
7728 alkind_unparse (oldKind)),
7729 uentry_whereDeclared (unew)))
7731 uentry_showWhereSpecified (old);
7733 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7734 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7735 sRef_setAliasKind (old->sref, AK_ERROR,
7736 uentry_whereDeclared (unew));
7740 sRef_setAliasKind (old->sref, newKind,
7741 uentry_whereDeclared (unew));
7746 if (!(alkind_isImplicit (newKind)))
7749 !uentry_isFunction (unew) &&
7752 message ("%s %q inconsistently %rdeclared %s %s storage, "
7753 "implicitly %s as temp storage",
7754 uentry_ekindName (unew),
7755 uentry_getName (unew),
7756 uentry_isDeclared (old),
7758 alkind_unparse (newKind),
7759 uentry_specOrDefName (old)),
7760 uentry_whereDeclared (unew)))
7762 uentry_showWhereSpecified (old);
7766 sRef_setAliasKind (old->sref, newKind,
7767 uentry_whereDeclared (unew));
7769 else /* newKind is temp or refcounted */
7776 else /* newKind unknown */
7783 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7784 bool mustConform, bool completeConform)
7789 oldKind = sRef_getExKind (old->sref);
7790 newKind = sRef_getExKind (unew->sref);
7792 if (exkind_isKnown (newKind))
7794 if (oldKind != newKind)
7796 if (exkind_isKnown (oldKind))
7801 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7802 uentry_ekindName (unew),
7803 uentry_getName (unew),
7804 uentry_isDeclared (old),
7806 exkind_unparse (newKind),
7807 uentry_specOrDefName (old),
7808 exkind_unparse (oldKind)),
7809 uentry_whereDeclared (unew)))
7811 uentry_showWhereSpecified (old);
7814 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7821 message ("%s %q inconsistently %rdeclared %s %s, "
7822 "implicitly %s without exposure qualifier",
7823 uentry_ekindName (unew),
7824 uentry_getName (unew),
7825 uentry_isDeclared (old),
7827 exkind_unparse (newKind),
7828 uentry_specOrDefName (old)),
7829 uentry_whereDeclared (unew)))
7831 uentry_showWhereSpecified (old);
7834 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7840 if (completeConform && exkind_isKnown (oldKind)
7841 && uentry_isReallySpecified (old))
7845 message ("%s %q specified as %s, but declared without "
7846 "exposure qualifier",
7847 ekind_capName (unew->ukind),
7848 uentry_getName (unew),
7849 exkind_unparse (oldKind)),
7850 uentry_whereDeclared (unew)))
7852 uentry_showWhereSpecified (old);
7856 /* yes, this is necessary! (if its a param) */
7857 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7862 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7863 bool mustConform, /*@unused@*/ bool completeConform)
7865 valueTable newvals = sRef_getValueTable (unew->sref);
7867 if (valueTable_isDefined (newvals))
7869 DPRINTF (("Check meta state: %s -> %s",
7870 uentry_unparseFull (old),
7871 uentry_unparseFull (unew)));
7873 DPRINTF (("Check meta state refs: %s -> %s",
7874 sRef_unparseFull (old->sref),
7875 sRef_unparseFull (unew->sref)));
7877 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7880 ** Copy the new values into the old ref
7883 valueTable_elements (newvals, key, newval)
7885 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7886 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7888 llassert (metaStateInfo_isDefined (msinfo));
7890 if (stateValue_isUndefined (oldval))
7892 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7896 if (stateValue_isError (oldval))
7898 if (!stateValue_isError (newval))
7900 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7904 ; /* No change necessary. */
7909 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7911 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7917 if (!stateValue_isError (newval)
7918 && !stateValue_isImplicit (newval))
7920 if (uentry_hasName (unew)
7921 || !sRef_isParam (uentry_getSref (unew)))
7926 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7927 uentry_ekindName (unew),
7928 uentry_getName (unew),
7929 uentry_isDeclared (old),
7931 stateValue_unparseValue (newval, msinfo),
7932 uentry_specOrDefName (old),
7933 stateValue_unparseValue (oldval, msinfo)),
7934 uentry_whereDeclared (unew)))
7936 uentry_showWhereSpecified (old);
7944 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7945 uentry_ekindName (unew),
7946 sRef_getParam (uentry_getSref (unew)),
7947 uentry_isDeclared (old),
7949 stateValue_unparseValue (newval, msinfo),
7950 uentry_specOrDefName (old),
7951 stateValue_unparseValue (oldval, msinfo)),
7952 uentry_whereDeclared (unew)))
7954 uentry_showWhereSpecified (old);
7960 DPRINTF (("Updating!"));
7961 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7965 DPRINTF (("Values match"));
7969 } end_valueTable_elements ;
7974 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7975 /*@notnull@*/ uentry unew,
7976 bool mustConform, bool completeConform)
7978 checkDefState (old, unew, mustConform, completeConform);
7979 checkNullState (old, unew, mustConform, completeConform);
7980 checkAliasState (old, unew, mustConform, completeConform);
7981 checkExpState (old, unew, mustConform, completeConform);
7982 checkMetaState (old, unew, mustConform, completeConform);
7984 sRef_storeState (old->sref);
7985 sRef_storeState (unew->sref);
7989 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7991 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7996 llassert (uentry_isVar (old));
7997 llassert (uentry_isVar (unew));
7999 if (cstring_isEmpty (old->uname))
8001 cstring_free (old->uname);
8002 old->uname = cstring_copy (unew->uname);
8005 if (unew->info->var->kind == VKRETPARAM
8006 || unew->info->var->kind == VKSEFRETPARAM)
8008 if (old->info->var->kind != VKRETPARAM
8009 && old->info->var->kind != VKSEFRETPARAM)
8013 message ("Parameter %q inconsistently %rdeclared as "
8014 "returned parameter",
8015 uentry_getName (unew),
8016 uentry_isDeclared (old)),
8017 uentry_whereDeclared (unew)))
8019 uentry_showWhereSpecified (old);
8020 old->info->var->kind = unew->info->var->kind;
8026 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8028 if (old->info->var->kind != VKSEFPARAM
8029 && old->info->var->kind != VKSEFRETPARAM)
8033 message ("Parameter %qinconsistently %rdeclared as "
8035 uentry_getOptName (unew),
8036 uentry_isDeclared (old)),
8037 uentry_whereDeclared (unew)))
8039 uentry_showWhereSpecified (old);
8040 old->info->var->kind = unew->info->var->kind;
8045 if (old->info->var->kind == VKSPEC)
8047 old->info->var->kind = unew->info->var->kind;
8051 unew->info->var->kind = old->info->var->kind;
8054 if (unew->info->var->checked != CH_UNKNOWN
8055 && unew->info->var->checked != old->info->var->checked)
8057 if (old->info->var->checked == CH_UNKNOWN
8058 && !fileloc_isUser (uentry_whereLast (old)))
8066 message ("Variable %q inconsistently %rdeclared as "
8067 "%s parameter (was %s)",
8068 uentry_getName (unew),
8069 uentry_isDeclared (old),
8070 checkedName (unew->info->var->checked),
8071 checkedName (old->info->var->checked)),
8072 uentry_whereDeclared (unew)))
8074 uentry_showWhereSpecified (old);
8078 old->info->var->checked = unew->info->var->checked;
8083 && (old->info->var->checked != CH_UNKNOWN)
8084 && uentry_isReallySpecified (old))
8088 message ("%s %q specified as %s, but declared without %s qualifier",
8089 ekind_capName (unew->ukind),
8090 uentry_getName (unew),
8091 checkedName (old->info->var->checked),
8092 checkedName (old->info->var->checked)),
8093 uentry_whereDeclared (unew)))
8095 uentry_showWhereSpecified (old);
8099 unew->info->var->checked = old->info->var->checked;
8102 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8105 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8107 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8112 llassert (uentry_isVar (u1));
8113 llassert (uentry_isVar (u2));
8115 if (u1->info->var->kind != u2->info->var->kind) {
8116 if (u1->info->var->kind == VKSEFRETPARAM) {
8117 if (u2->info->var->kind == VKRETPARAM) {
8120 message ("Function types are inconsistent. Parameter %d is "
8121 "sef parameter, but non-sef parameter in "
8122 "assigned function: %s",
8123 paramno, exprNode_unparse (e)),
8125 } else if (u2->info->var->kind == VKSEFPARAM) {
8128 message ("Function types are inconsistent. Parameter %d is "
8129 "returns parameter, but non-returns parameter in "
8130 "assigned function: %s",
8131 paramno, exprNode_unparse (e)),
8136 message ("Function types are inconsistent. Parameter %d is "
8137 "sef returns parameter, but non-sef returns parameter in "
8138 "assigned function: %s",
8139 paramno, exprNode_unparse (e)),
8142 } else if (u1->info->var->kind == VKRETPARAM) {
8145 message ("Function types are inconsistent. Parameter %d is "
8146 "returns parameter, but non-returns parameter in "
8147 "assigned function: %s",
8148 paramno, exprNode_unparse (e)),
8150 } else if (u1->info->var->kind == VKSEFPARAM) {
8153 message ("Function types are inconsistent. Parameter %d is "
8154 "sef parameter, but non-sef parameter in "
8155 "assigned function: %s",
8156 paramno, exprNode_unparse (e)),
8159 if (u2->info->var->kind == VKSEFRETPARAM) {
8162 message ("Function types are inconsistent. Parameter %d is "
8163 "normal parameter, but sef returns parameter in "
8164 "assigned function: %s",
8165 paramno, exprNode_unparse (e)),
8167 } else if (u2->info->var->kind == VKSEFPARAM) {
8170 message ("Function types are inconsistent. Parameter %d is "
8171 "normal parameter, but sef parameter in "
8172 "assigned function: %s",
8173 paramno, exprNode_unparse (e)),
8175 } else if (u2->info->var->kind == VKRETPARAM) {
8178 message ("Function types are inconsistent. Parameter %d is "
8179 "normal parameter, but returns parameter in "
8180 "assigned function: %s",
8181 paramno, exprNode_unparse (e)),
8189 if (u1->info->var->defstate != u2->info->var->defstate)
8193 message ("Function types are inconsistent. Parameter %d is "
8194 "%s, but %s in assigned function: %s",
8196 sstate_unparse (u1->info->var->defstate),
8197 sstate_unparse (u2->info->var->defstate),
8198 exprNode_unparse (e)),
8202 if (u1->info->var->nullstate != u2->info->var->nullstate)
8206 message ("Function types are inconsistent. Parameter %d is "
8207 "%s, but %s in assigned function: %s",
8209 nstate_unparse (u1->info->var->nullstate),
8210 nstate_unparse (u2->info->var->nullstate),
8211 exprNode_unparse (e)),
8215 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8219 message ("Function types are inconsistent. Parameter %d is "
8220 "%s, but %s in assigned function: %s",
8222 alkind_unparse (sRef_getAliasKind (u1->sref)),
8223 alkind_unparse (sRef_getAliasKind (u2->sref)),
8224 exprNode_unparse (e)),
8228 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8232 message ("Function types are inconsistent. Parameter %d is "
8233 "%s, but %s in assigned function: %s",
8235 exkind_unparse (sRef_getExKind (u1->sref)),
8236 exkind_unparse (sRef_getExKind (u2->sref)),
8237 exprNode_unparse (e)),
8243 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8244 /*@notnull@*/ uentry unew,
8245 bool mustConform, /*@unused@*/ bool completeConform)
8247 uentryList oldParams = uentry_getParams (old);
8248 uentryList newParams = uentry_getParams (unew);
8249 ctype newType = unew->utype;
8250 ctype oldType = ctype_realType (old->utype);
8251 ctype oldRetType = ctype_unknown;
8252 ctype newRetType = ctype_unknown;
8254 DPRINTF (("Function conform: %s ==> %s",
8255 uentry_unparseFull (old),
8256 uentry_unparseFull (unew)));
8258 if (uentry_isForward (old))
8260 mustConform = FALSE;
8261 uentry_updateInto (old, unew);
8266 ** check return values
8269 if (ctype_isKnown (oldType))
8271 llassert (ctype_isFunction (oldType));
8272 oldRetType = ctype_getReturnType (oldType);
8275 if (ctype_isKnown (newType))
8277 llassert (ctype_isFunction (newType));
8278 newRetType = ctype_getReturnType (newType);
8281 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8282 && !ctype_matchDef (newRetType, oldRetType))
8284 if (mustConform) returnValueError (old, unew);
8288 if (ctype_isConj (newRetType))
8290 if (ctype_isConj (oldRetType))
8292 if (!ctype_sameAltTypes (newRetType, oldRetType))
8296 message ("Function %q inconsistently %rdeclared to "
8297 "return alternate types %s "
8298 "(types match, but alternates are not identical, "
8299 "so checking may not be correct)",
8300 uentry_getName (unew),
8301 uentry_isDeclared (old),
8302 ctype_unparse (newRetType)),
8303 uentry_whereDeclared (unew)))
8305 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8311 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8316 DPRINTF (("Before state: %s",
8317 uentry_unparseFull (old)));
8318 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8319 DPRINTF (("After state: %s",
8320 uentry_unparseFull (old)));
8322 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8324 if (exitkind_isKnown (unew->info->fcn->exitCode))
8328 message ("Function %q inconsistently %rdeclared using %s",
8329 uentry_getName (unew),
8330 uentry_isDeclared (old),
8331 exitkind_unparse (unew->info->fcn->exitCode)),
8332 uentry_whereDeclared (unew)))
8334 uentry_showWhereSpecified (old);
8339 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8343 if (!qual_isUnknown (unew->info->fcn->nullPred))
8345 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8349 message ("Function %q inconsistently %rdeclared using %s",
8350 uentry_getName (unew),
8351 uentry_isDeclared (old),
8352 qual_unparse (unew->info->fcn->nullPred)),
8353 uentry_whereDeclared (unew)))
8355 uentry_showWhereSpecified (old);
8361 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8364 if (unew->info->fcn->specialCode != SPC_NONE)
8366 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8370 message ("Function %q inconsistently %rdeclared using %s",
8371 uentry_getName (unew),
8372 uentry_isDeclared (old),
8373 specCode_unparse (unew->info->fcn->specialCode)),
8374 uentry_whereDeclared (unew)))
8376 uentry_showWhereSpecified (old);
8382 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8389 if (!uentryList_sameObject (oldParams, newParams)
8390 && (!uentryList_isMissingParams (oldParams)))
8392 if (!uentryList_isMissingParams (newParams))
8395 int nparams = uentryList_size (oldParams);
8396 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8398 if (nparams != uentryList_size (newParams))
8400 nargsError (old, unew);
8403 if (uentryList_size (newParams) < nparams)
8405 nparams = uentryList_size (newParams);
8408 while (paramno < nparams)
8410 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8411 uentry newCurrent = uentryList_getN (newParams, paramno);
8412 ctype oldCurrentType = uentry_getType (oldCurrent);
8413 ctype newCurrentType = uentry_getType (newCurrent);
8415 llassert (uentry_isValid (oldCurrent)
8416 && uentry_isValid (newCurrent));
8418 if (!uentry_isElipsisMarker (oldCurrent)
8419 && !uentry_isElipsisMarker (newCurrent))
8421 checkVarConformance (oldCurrent, newCurrent,
8422 mustConform, completeConform);
8427 if (uentry_hasName (oldCurrent)
8428 && uentry_hasName (newCurrent))
8430 cstring oldname = uentry_getName (oldCurrent);
8431 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8433 cstring nname = uentry_getName (newCurrent);
8436 if (cstring_isDefined (pfx)
8437 && cstring_equalPrefix (oldname, pfx))
8439 oname = cstring_suffix (oldname, cstring_length (pfx));
8444 /*@-branchstate@*/ } /*@=branchstate@*/
8446 if (cstring_isDefined (pfx)
8447 && cstring_equalPrefix (nname, pfx))
8449 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8454 /*@-branchstate@*/ } /*@=branchstate@*/
8456 if (!cstring_equal (oname, nnamefix))
8459 (FLG_DECLPARAMMATCH,
8460 message ("Definition parameter name %s does not match "
8461 "name of corresponding parameter in "
8464 uentry_whereLast (newCurrent)))
8466 uentry_showWhereLastPlain (oldCurrent);
8470 cstring_free (oldname);
8471 cstring_free (nname);
8475 if (!ctype_match (oldCurrentType, newCurrentType))
8477 paramTypeError (old, oldCurrent, oldCurrentType,
8478 unew, newCurrent, newCurrentType, paramno);
8482 if (ctype_isMissingParamsMarker (newCurrentType)
8483 || ctype_isElips (newCurrentType)
8484 || ctype_isMissingParamsMarker (oldCurrentType)
8485 || ctype_isElips (oldCurrentType))
8491 if (ctype_isConj (newCurrentType))
8493 if (ctype_isConj (oldCurrentType))
8495 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8499 message ("Parameter %q inconsistently %rdeclared with "
8500 "alternate types %s "
8501 "(types match, but alternates are not identical, "
8502 "so checking may not be correct)",
8503 uentry_getName (newCurrent),
8504 uentry_isDeclared (oldCurrent),
8505 ctype_unparse (newCurrentType)),
8506 uentry_whereDeclared (unew)))
8508 uentry_showWhereLastVal (oldCurrent,
8509 ctype_unparse (oldCurrentType));
8517 message ("Parameter %q inconsistently %rdeclared with "
8518 "alternate types %s",
8519 uentry_getName (newCurrent),
8520 uentry_isDeclared (oldCurrent),
8521 ctype_unparse (newCurrentType)),
8522 uentry_whereDeclared (unew)))
8524 uentry_showWhereLastVal (oldCurrent,
8525 ctype_unparse (oldCurrentType));
8532 if (ctype_isConj (oldCurrentType))
8534 uentry_setType (newCurrent, oldCurrentType);
8542 ** Forgot this! detected by splint:
8543 ** uentry.c:1257,15: Suspected infinite loop
8549 if (!uentryList_isMissingParams (newParams))
8551 if (ctype_isConj (oldRetType))
8553 old->utype = ctype_makeFunction (oldRetType,
8554 uentryList_copy (newParams));
8558 old->utype = unew->utype;
8562 checkGlobalsConformance (old, unew, mustConform, completeConform);
8563 checkModifiesConformance (old, unew, mustConform, completeConform);
8565 DPRINTF (("Before list: %s",
8566 uentry_unparseFull (old)));
8568 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8570 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8575 message ("Function %q redeclared using special clauses (can only "
8576 "be used in first declaration)",
8577 uentry_getName (unew)),
8578 uentry_whereDeclared (unew)))
8580 uentry_showWhereLast (old);
8584 /*@i23 need checking @*/
8586 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8590 /*@i43 should be able to append? @*/
8592 stateClauseList_checkEqual (old, unew);
8593 stateClauseList_free (unew->info->fcn->specclauses);
8594 unew->info->fcn->specclauses = stateClauseList_undefined;
8598 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8600 if (fileloc_isUndefined (old->whereDeclared))
8602 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8604 else if (fileloc_isUndefined (unew->whereDeclared))
8606 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8615 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8619 llassert (uentry_isValid (ue));
8620 llassert (uentry_isEitherConstant (ue));
8622 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8623 uval = uentry_getConstantValue (ue);
8625 if (multiVal_isDefined (uval))
8627 if (multiVal_isDefined (m))
8629 if (!multiVal_equiv (uval, m))
8633 message ("%s %q defined with inconsistent value: %q",
8634 ekind_capName (ue->ukind),
8635 uentry_getName (ue),
8636 multiVal_unparse (m)),
8639 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8647 uentry_setConstantValue (ue, m);
8652 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8655 bool typeError = FALSE;
8657 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8659 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8663 DPRINTF (("Check struct conformance: %s / %s",
8664 uentry_unparseFull (old),
8665 uentry_unparseFull (unew)));
8666 checkStructConformance (old, unew);
8671 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8673 llbug (message ("struct tags: bad types: %t / %t",
8674 old->utype, unew->utype));
8678 else if (uentry_isEnumTag (old))
8680 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8682 if (mustConform) checkEnumConformance (old, unew);
8686 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8688 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8689 ctype_unparse (unew->utype)));
8693 else if (!ctype_match (old->utype, unew->utype))
8695 DPRINTF (("Type mismatch: %s / %s",
8696 ctype_unparse (old->utype),
8697 ctype_unparse (unew->utype)));
8699 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8701 ctype realt = ctype_realType (unew->utype);
8703 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8705 unew->utype = ctype_bool;
8711 typeError = optgenerror
8713 message ("%q defined as %s", uentry_getName (old),
8714 ctype_unparse (realt)),
8715 uentry_whereDeclared (unew));
8723 ctype oldr = ctype_realType (old->utype);
8724 ctype newr = ctype_realType (unew->utype);
8726 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8728 checkStructConformance (old, unew);
8730 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8732 checkStructConformance (old, unew);
8734 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8736 checkEnumConformance (old, unew);
8738 else if (uentry_isConstant (old)
8739 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8741 /* okay...for now! (should check the type is reset later... */
8745 DPRINTF (("YABA!"));
8748 message ("%s %q %rdeclared with inconsistent type: %t",
8749 ekind_capName (unew->ukind),
8750 uentry_getName (unew),
8751 uentry_isDeclared (old),
8753 uentry_whereDeclared (unew)))
8755 uentry_showWhereLast (old);
8771 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8772 /*@notnull@*/ uentry unew,
8773 bool mustConform, bool completeConform)
8775 if (ctype_isDefined (unew->info->datatype->type))
8778 ** bool is hard coded here, since it is built into LCL.
8779 ** For now, we're stuck with LCL's types.
8782 if (ctype_isDirectBool (old->utype) &&
8783 cstring_equalLit (unew->uname, "bool"))
8785 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8786 evs 2000-07-25: removed
8788 unew->utype = ctype_bool;
8791 if (ctype_isUnknown (old->info->datatype->type))
8793 old->info->datatype->type = unew->info->datatype->type;
8797 DPRINTF (("Old: %s / New: %s",
8798 uentry_unparseFull (old),
8799 uentry_unparseFull (unew)));
8800 DPRINTF (("Types: %s / %s",
8801 ctype_unparse (old->info->datatype->type),
8802 ctype_unparse (unew->info->datatype->type)));
8804 if (ctype_matchDef (old->info->datatype->type,
8805 unew->info->datatype->type))
8814 ("Type %q %s with inconsistent type: %t",
8815 uentry_getName (unew),
8816 uentry_reDefDecl (old, unew),
8817 unew->info->datatype->type),
8818 uentry_whereDeclared (unew)))
8820 uentry_showWhereLastExtra
8821 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8824 old->info->datatype->type = unew->info->datatype->type;
8829 if (unew->info->datatype->abs != MAYBE)
8831 if (ynm_isOff (old->info->datatype->abs)
8832 && ynm_isOn (unew->info->datatype->abs))
8834 if (!ctype_isDirectBool (old->utype))
8839 ("Datatype %q inconsistently %rdeclared as abstract type",
8840 uentry_getName (unew),
8841 uentry_isDeclared (old)),
8842 uentry_whereDeclared (unew)))
8844 uentry_showWhereLastPlain (old);
8848 else if (ynm_isOn (old->info->datatype->abs)
8849 && ynm_isOff (unew->info->datatype->abs))
8851 if (!ctype_isDirectBool (old->utype))
8856 ("Datatype %q inconsistently %rdeclared as concrete type",
8857 uentry_getName (unew),
8858 uentry_isDeclared (old)),
8859 uentry_whereDeclared (unew)))
8861 uentry_showWhereLastPlain (old);
8872 if (ynm_isOn (old->info->datatype->abs))
8874 old->sref = unew->sref;
8875 unew->info->datatype->mut = old->info->datatype->mut;
8878 && uentry_isReallySpecified (old))
8883 ("Datatype %q specified as abstract, "
8884 "but abstract annotation not used in declaration",
8885 uentry_getName (unew)),
8886 uentry_whereDeclared (unew)))
8888 uentry_showWhereLastPlain (old);
8894 unew->info->datatype->abs = old->info->datatype->abs;
8896 if (ynm_isMaybe (unew->info->datatype->mut))
8898 if (completeConform && ynm_isOff (old->info->datatype->mut)
8899 && uentry_isReallySpecified (old))
8904 ("Datatype %q specified as immutable, "
8905 "but immutable annotation not used in declaration",
8906 uentry_getName (unew)),
8907 uentry_whereDeclared (unew)))
8909 uentry_showWhereLastPlain (old);
8913 unew->info->datatype->mut = old->info->datatype->mut;
8915 else if (ynm_isMaybe (old->info->datatype->mut))
8917 old->info->datatype->mut = unew->info->datatype->mut;
8921 if (ynm_isOn (old->info->datatype->abs))
8923 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8927 message ("Datatype %q inconsistently %rdeclared as immutable",
8928 uentry_getName (unew),
8929 uentry_isDeclared (old)),
8930 uentry_whereDeclared (unew)))
8932 uentry_showWhereLastPlain (old);
8937 if (ynm_isOff (old->info->datatype->mut)
8938 && ynm_isOn (unew->info->datatype->mut))
8942 message ("Datatype %q inconsistently %rdeclared as mutable",
8943 uentry_getName (unew),
8944 uentry_isDeclared (old)),
8945 uentry_whereDeclared (unew)))
8947 uentry_showWhereLastPlain (old);
8952 old->info->datatype->mut = unew->info->datatype->mut;
8955 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8959 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8960 /*@notnull@*/ uentry unew,
8962 /*@unused@*/ bool completeConform)
8964 multiVal oldval = uentry_getConstantValue (old);
8965 multiVal newval = uentry_getConstantValue (unew);
8967 if (multiVal_isDefined (oldval))
8969 if (multiVal_isDefined (newval))
8971 if (!multiVal_equiv (oldval, newval))
8976 message ("%s %q %rdeclared with inconsistent value: %q",
8977 ekind_capName (unew->ukind),
8978 uentry_getName (unew),
8979 uentry_isDeclared (old),
8980 multiVal_unparse (newval)),
8981 uentry_whereDeclared (unew)))
8983 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8987 uentry_setConstantValue (unew, multiVal_copy (oldval));
8996 uentry_setConstantValue (old, multiVal_copy (newval));
9001 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9002 /*@notnull@*/ uentry unew, bool mustConform,
9003 bool completeConform)
9005 bool typeError = FALSE;
9006 bool fcnConformance = FALSE;
9008 if (!ekind_equal (unew->ukind, old->ukind))
9011 ** okay, only if one is a function and the other is
9012 ** a variable of type function.
9015 if (unew->ukind == KENUMCONST
9016 && old->ukind == KCONST)
9018 old->ukind = KENUMCONST;
9022 if (unew->ukind == KFCN
9023 && old->ukind == KCONST
9024 && ctype_isUnknown (old->utype))
9027 ** When a function is defined with an unparam macro
9030 uentry_updateInto (old, unew);
9034 if (uentry_isExpandedMacro (old)
9035 && uentry_isEitherConstant (unew))
9037 uentry_updateInto (old, unew);
9041 if (uentry_isEndIter (unew))
9043 if (ctype_isUnknown (old->utype))
9045 if (!uentry_isSpecified (old)
9046 && uentry_isCodeDefined (unew))
9048 if (!fileloc_withinLines (uentry_whereDefined (old),
9049 uentry_whereDeclared (unew), 2))
9050 { /* bogus! will give errors if there is too much whitespace */
9054 ("Iterator finalized name %q does not match name in "
9055 "previous iter declaration (should be end_%q). This iter "
9056 "is declared at %q",
9057 uentry_getName (unew),
9058 uentry_getName (old),
9059 fileloc_unparse (uentry_whereDefined (old))),
9060 uentry_whereDeclared (old));
9064 uentry_updateInto (old, unew);
9069 KindConformanceError (old, unew, mustConform);
9073 if (uentry_isFunction (unew))
9075 if (uentry_isVariable (old))
9077 if (!ctype_isUnknown (old->utype))
9079 if (ctype_isFunction (old->utype))
9081 uentry_makeVarFunction (old);
9082 checkFunctionConformance (old, unew, mustConform,
9084 fcnConformance = TRUE;
9088 KindConformanceError (old, unew, mustConform);
9093 if (uentry_isExpandedMacro (old))
9095 if (fileloc_isUndefined (unew->whereDefined))
9097 unew->whereDefined = fileloc_update (unew->whereDefined,
9101 uentry_updateInto (old, unew);
9102 old->used = unew->used = TRUE;
9107 /* undeclared identifier */
9108 old->utype = unew->utype;
9109 uentry_makeVarFunction (old);
9110 checkFunctionConformance (old, unew, FALSE, FALSE);
9111 fcnConformance = TRUE;
9117 KindConformanceError (old, unew, mustConform);
9120 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9122 if (!ctype_isUnknown (unew->utype))
9124 if (ctype_isFunction (unew->utype))
9126 uentry_makeVarFunction (unew);
9127 checkFunctionConformance (old, unew, mustConform, completeConform);
9128 fcnConformance = TRUE;
9132 KindConformanceError (old, unew, mustConform);
9137 KindConformanceError (old, unew, mustConform);
9142 KindConformanceError (old, unew, mustConform);
9148 ** check parameter lists for functions
9149 ** (before type errors, to get better messages
9152 if (uentry_isFunction (old))
9154 checkFunctionConformance (old, unew, mustConform, completeConform);
9155 fcnConformance = TRUE;
9159 if (!ctype_isUndefined (old->utype))
9161 typeError = checkTypeConformance (old, unew, mustConform);
9168 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9170 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9173 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9175 DPRINTF (("Check datatype: %s / %s",
9176 uentry_unparseFull (old),
9177 uentry_unparseFull (unew)));
9179 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9182 if (uentry_isVariable (old) && uentry_isVariable (unew))
9185 !ctype_matchDef (old->utype, unew->utype))
9190 ("Variable %q %s with inconsistent type (arrays and pointers are "
9191 "not identical in variable declarations): %t",
9192 uentry_getName (unew),
9193 uentry_reDefDecl (old, unew),
9195 uentry_whereDeclared (unew)))
9197 uentry_showWhereLast (old);
9200 ** Avoid repeated errors.
9203 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9205 old->whereDefined = fileloc_update (old->whereDefined,
9213 checkVarConformance (old, unew, mustConform, completeConform);
9218 /* old->utype = unew->utype; */
9222 if (ctype_isConj (old->utype))
9224 if (ctype_isConj (unew->utype))
9226 if (!ctype_sameAltTypes (old->utype, unew->utype))
9230 message ("%s %q inconsistently %rdeclared with "
9231 "alternate types %s "
9232 "(types match, but alternates are not identical, "
9233 "so checking may not be correct)",
9234 ekind_capName (uentry_getKind (old)),
9235 uentry_getName (unew),
9236 uentry_isDeclared (old),
9237 ctype_unparse (unew->utype)),
9238 uentry_whereDeclared (unew)))
9240 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9244 old->utype = unew->utype;
9251 if (ctype_isUnknown (old->utype))
9253 old->utype = unew->utype;
9258 if (unew->ukind == old->ukind)
9261 unew->info = uinfo_copy (old->info, old->ukind);
9264 sRef_storeState (old->sref);
9265 sRef_storeState (unew->sref);
9268 static void uentry_mergeConstraints (uentry spec, uentry def)
9270 if (uentry_isFunction (def))
9272 DPRINTF (("Here: %s / %s",
9273 uentry_unparseFull (spec),
9274 uentry_unparseFull (def)));
9275 /* evans 2001-07-21 */
9276 llassert (uentry_isFunction (spec));
9278 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9280 if (fileloc_isXHFile (uentry_whereLast (def)))
9282 llassert (uentry_isFunction (spec));
9283 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9284 def->info->fcn->preconditions);
9286 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9292 /* Check if the constraints are identical */
9297 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9298 uentry_getName (spec),
9299 functionConstraint_unparse (spec->info->fcn->preconditions)),
9300 uentry_whereLast (def)))
9302 uentry_showWhereSpecified (spec);
9305 functionConstraint_free (spec->info->fcn->preconditions);
9306 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9309 def->info->fcn->preconditions = functionConstraint_undefined;
9312 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9314 if (fileloc_isXHFile (uentry_whereLast (def)))
9316 llassert (uentry_isFunction (spec));
9317 DPRINTF (("Post: %s /++/ %s",
9318 functionConstraint_unparse (spec->info->fcn->postconditions),
9319 functionConstraint_unparse (def->info->fcn->postconditions)));
9320 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9321 def->info->fcn->postconditions);
9322 def->info->fcn->postconditions = functionConstraint_undefined;
9323 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9330 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9331 uentry_getName (spec),
9332 functionConstraint_unparse (spec->info->fcn->postconditions)),
9333 uentry_whereLast (def)))
9335 uentry_showWhereSpecified (spec);
9338 functionConstraint_free (spec->info->fcn->postconditions);
9339 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9340 def->info->fcn->postconditions = functionConstraint_undefined;
9347 ** modifies spec to reflect def, reports any inconsistencies
9351 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9353 llassert (uentry_isValid (spec));
9354 llassert (uentry_isValid (def));
9355 llassert (cstring_equal (spec->uname, def->uname));
9357 if (uentry_isFunction (def))
9359 if (uentry_isConstant (spec))
9361 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9362 uentry_makeConstantFunction (spec);
9366 uentry_convertVarFunction (spec);
9369 llassert (uentry_isFunction (spec));
9372 DPRINTF (("Merge entries: %s / %s",
9373 uentry_unparseFull (spec),
9374 uentry_unparseFull (def)));
9376 uentry_mergeConstraints (spec, def);
9378 uentry_checkConformance (spec, def, TRUE,
9379 context_getFlag (FLG_NEEDSPEC));
9381 DPRINTF (("Merge entries after conform: %s / %s",
9382 uentry_unparseFull (spec),
9383 uentry_unparseFull (def)));
9385 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9388 ** okay, declarations conform. Propagate extra information.
9391 uentry_setDefined (spec, uentry_whereDefined (def));
9392 uentry_setDeclared (spec, uentry_whereDeclared (def));
9394 if (uentry_isStatic (def))
9398 message ("%s %q specified, but declared as static",
9399 ekind_capName (def->ukind),
9400 uentry_getName (def)),
9401 uentry_whereDeclared (def)))
9403 uentry_showWhereSpecified (spec);
9408 spec->storageclass = def->storageclass;
9411 sRef_storeState (spec->sref);
9413 spec->used = def->used || spec->used;
9414 spec->hasNameError |= def->hasNameError;
9418 if (!spec->hasNameError)
9420 uentry_checkName (spec);
9429 ** Can't generate function redeclaration errors when the
9430 ** entries are merged, since we don't yet know if its the
9431 ** definition of the function.
9435 uentry_clearDecl (void)
9437 posRedeclared = uentry_undefined;
9438 fileloc_free (posLoc);
9439 posLoc = fileloc_undefined;
9443 uentry_checkDecl (void)
9445 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9447 llassert (fileloc_isDefined (posLoc));
9449 if (uentry_isCodeDefined (posRedeclared))
9451 if (optgenerror (FLG_REDECL,
9452 message ("%s %q declared after definition",
9453 ekind_capName (posRedeclared->ukind),
9454 uentry_getName (posRedeclared)),
9457 llgenindentmsg (message ("Definition of %q",
9458 uentry_getName (posRedeclared)),
9459 posRedeclared->whereDeclared);
9464 if (optgenerror (FLG_REDECL,
9465 message ("%s %q declared more than once",
9466 ekind_capName (posRedeclared->ukind),
9467 uentry_getName (posRedeclared)),
9470 llgenindentmsg (message ("Previous declaration of %q",
9471 uentry_getName (posRedeclared)),
9472 posRedeclared->whereDeclared);
9477 fileloc_free (posLoc);
9478 posLoc = fileloc_undefined;
9479 posRedeclared = uentry_undefined;
9483 ** Redefinition of old as unew.
9484 ** modifies old to reflect unew, reports any inconsistencies
9488 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9490 fileloc olddef = uentry_whereDeclared (old);
9491 fileloc unewdef = uentry_whereDeclared (unew);
9495 DPRINTF (("uentry merge: %s / %s",
9496 uentry_unparseFull (old),
9497 uentry_unparseFull (unew)));
9500 fileloc_isUndefined (olddef)
9501 && fileloc_isDefined (uentry_whereDefined (old))
9502 && !uentry_isExpandedMacro (old);
9504 if (!context_getFlag (FLG_INCONDEFSLIB)
9505 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9507 mustConform = FALSE;
9514 llassert (uentry_isValid (old));
9515 llassert (uentry_isValid (unew));
9516 llassert (cstring_equal (old->uname, unew->uname));
9518 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9520 if (uentry_isConstant (old))
9522 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9523 uentry_makeConstantFunction (old);
9527 uentry_convertVarFunction (old);
9530 llassert (uentry_isFunction (old));
9533 DPRINTF (("uentry merge: %s / %s",
9534 uentry_unparseFull (old),
9535 uentry_unparseFull (unew)));
9537 if (uentry_isExtern (unew))
9539 uentry_setUsed (old, unewdef);
9543 ** should check old one was extern!
9546 if (uentry_isStatic (old))
9548 if (!(uentry_isStatic (unew)))
9552 message ("%s %q shadows static declaration",
9553 ekind_capName (unew->ukind),
9554 uentry_getName (unew)),
9557 uentry_showWhereLast (old);
9562 uentry_setDeclDef (old, unewdef);
9565 else if (uentry_isStatic (unew))
9567 uentry_setDeclDef (old, unewdef);
9569 else if (uentry_isExtern (old))
9571 uentry_setDeclared (old, unewdef);
9575 if (!uentry_isExtern (unew)
9576 && !uentry_isForward (old)
9577 && !fileloc_equal (olddef, unewdef)
9578 && !fileloc_isUndefined (olddef)
9579 && !fileloc_isUndefined (unewdef)
9580 && !fileloc_isBuiltin (olddef)
9581 && !fileloc_isBuiltin (unewdef)
9582 && !uentry_isYield (old)
9583 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9585 if (uentry_isVariable (old) || uentry_isVariable (unew))
9587 ; /* will report redeclaration error later */
9591 if (fileloc_isDefined (uentry_whereDefined (old)))
9595 message ("%s %q defined more than once",
9596 ekind_capName (unew->ukind),
9597 uentry_getName (unew)),
9598 uentry_whereLast (unew)))
9601 (message ("Previous definition of %q",
9602 uentry_getName (old)),
9603 uentry_whereLast (old));
9606 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9608 uentry_updateInto (old, unew);
9609 old->sref = sRef_saveCopy (old->sref);
9617 if (fileloc_isLib (olddef)
9618 || fileloc_isUndefined (olddef)
9619 || fileloc_isImport (olddef))
9621 if (uentry_isExtern (unew))
9623 if (uentry_isExtern (old)
9624 || (fileloc_isDefined (uentry_whereDeclared (old))
9625 && (!fileloc_equal (uentry_whereDeclared (old),
9626 uentry_whereDefined (old)))))
9630 message ("%s %q declared more than once",
9631 ekind_capName (unew->ukind),
9632 uentry_getName (unew)),
9633 unew->whereDeclared))
9636 (message ("Previous declaration of %q",
9637 uentry_getName (old)),
9638 old->whereDeclared);
9642 uentry_setExtern (old);
9646 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9652 DPRINTF (("uentry merge: %s / %s",
9653 uentry_unparseFull (old),
9654 uentry_unparseFull (unew)));
9656 uentry_mergeConstraints (old, unew);
9657 DPRINTF (("uentry merge: %s / %s",
9658 uentry_unparseFull (old),
9659 uentry_unparseFull (unew)));
9661 uentry_checkConformance (old, unew, mustConform, FALSE);
9662 DPRINTF (("uentry merge: %s / %s",
9663 uentry_unparseFull (old),
9664 uentry_unparseFull (unew)));
9666 old->used = old->used || unew->used;
9667 old->uses = filelocList_append (old->uses, unew->uses);
9668 unew->uses = filelocList_undefined;
9670 sRef_storeState (old->sref);
9671 sRef_storeState (unew->sref);
9675 old->whereDefined = fileloc_update (old->whereDefined,
9679 DPRINTF (("here: %s", uentry_unparseFull (old)));
9682 ** No redeclaration errors for functions here, since we
9683 ** don't know if this is the definition of the function.
9686 if (fileloc_isUser (old->whereDeclared)
9687 && fileloc_isUser (unew->whereDeclared)
9688 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9689 && !fileloc_isDefined (unew->whereDefined))
9691 if (uentry_isFunction (old))
9693 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9694 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9698 if (optgenerror (FLG_REDECL,
9699 message ("%s %q declared more than once",
9700 ekind_capName (unew->ukind),
9701 uentry_getName (unew)),
9702 unew->whereDeclared))
9704 llgenindentmsg (message ("Previous declaration of %q",
9705 uentry_getName (old)),
9706 old->whereDeclared);
9711 if (fileloc_isUndefined (old->whereDefined))
9713 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9717 if (!context_processingMacros ()
9718 && fileloc_isUser (old->whereDefined)
9719 && fileloc_isUser (unew->whereDefined)
9720 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9722 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9724 if (uentry_isVariable (unew)
9725 && uentry_isExtern (unew))
9727 if (optgenerror (FLG_REDECL,
9728 message ("%s %q declared after definition",
9729 ekind_capName (unew->ukind),
9730 uentry_getName (unew)),
9731 unew->whereDeclared))
9733 llgenindentmsg (message ("Definition of %q",
9734 uentry_getName (old)),
9740 if (optgenerror (FLG_REDEF,
9741 message ("%s %q redefined",
9742 ekind_capName (unew->ukind),
9743 uentry_getName (unew)),
9744 unew->whereDefined))
9746 llgenindentmsg (message ("Previous definition of %q",
9747 uentry_getName (old)),
9755 if (uentry_isExternal (unew))
9757 old->whereDefined = fileloc_createExternal ();
9760 if (unew->hasNameError)
9762 old->hasNameError = TRUE;
9767 if (!old->hasNameError)
9769 uentry_checkName (old);
9772 DPRINTF (("After: %s", uentry_unparseFull (old)));
9773 llassert (!ctype_isUndefined (old->utype));
9777 uentry_copyState (uentry res, uentry other)
9779 llassert (uentry_isValid (res));
9780 llassert (uentry_isValid (other));
9782 res->used = other->used;
9784 res->info->var->kind = other->info->var->kind;
9785 res->info->var->defstate = other->info->var->defstate;
9786 res->info->var->nullstate = other->info->var->nullstate;
9787 res->info->var->checked = other->info->var->checked;
9789 sRef_copyState (res->sref, other->sref);
9793 uentry_sameKind (uentry u1, uentry u2)
9795 if (uentry_isValid (u1) && uentry_isValid (u2))
9797 if (uentry_isVar (u1) && uentry_isVar (u2))
9799 ctype c1 = u1->utype;
9800 ctype c2 = u2->utype;
9802 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9805 ** both functions, or both not functions
9808 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9812 return ((u1->ukind == u2->ukind));
9819 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9821 ekind okind = unew->ukind;
9822 llassert (uentry_isValid (unew));
9823 llassert (uentry_isValid (old));
9825 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9827 unew->ukind = old->ukind;
9828 llassert (cstring_equal (unew->uname, old->uname));
9829 unew->utype = old->utype;
9831 if (fileloc_isDefined (unew->whereSpecified)
9832 && !fileloc_isDefined (old->whereSpecified))
9834 ; /* Keep the old value */
9838 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9839 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9842 if (fileloc_isDefined (unew->whereDefined)
9843 && !fileloc_isDefined (old->whereDefined))
9845 ; /* Keep the old value */
9849 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9850 unew->whereDefined = fileloc_copy (old->whereDefined);
9853 if (fileloc_isDefined (unew->whereDeclared)
9854 && !fileloc_isDefined (old->whereDeclared))
9856 ; /* Keep the old value */
9860 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9861 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9864 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9866 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9867 unew->used = old->used;
9869 unew->isPrivate = old->isPrivate;
9870 unew->hasNameError = old->hasNameError;
9871 unew->uses = filelocList_append (unew->uses, old->uses);
9872 old->uses = filelocList_undefined;
9874 unew->storageclass = old->storageclass;
9875 uinfo_free (unew->info, okind);
9876 unew->info = uinfo_copy (old->info, old->ukind);
9881 uentry_copy (uentry e)
9883 if (uentry_isValid (e))
9885 uentry enew = uentry_alloc ();
9886 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9887 enew->ukind = e->ukind;
9888 enew->uname = cstring_copy (e->uname);
9889 enew->utype = e->utype;
9891 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9892 enew->whereDefined = fileloc_copy (e->whereDefined);
9893 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9895 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9896 enew->used = e->used;
9898 enew->isPrivate = e->isPrivate;
9899 enew->hasNameError = e->hasNameError;
9900 enew->uses = filelocList_undefined;
9902 enew->storageclass = e->storageclass;
9903 enew->info = uinfo_copy (e->info, e->ukind);
9904 enew->warn = warnClause_copy (e->warn);
9906 DPRINTF (("Here we are..."));
9907 DPRINTF (("original: %s", uentry_unparseFull (e)));
9908 DPRINTF (("copy: %s", uentry_unparse (enew)));
9909 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9914 return uentry_undefined;
9919 uentry_setState (uentry res, uentry other)
9921 llassert (uentry_isValid (res));
9922 llassert (uentry_isValid (other));
9924 llassert (res->ukind == other->ukind);
9925 llassert (res->ukind == KVAR);
9927 res->sref = sRef_saveCopy (other->sref);
9928 res->used = other->used;
9929 filelocList_free (res->uses);
9930 res->uses = other->uses;
9931 other->uses = filelocList_undefined;
9932 res->lset = other->lset;
9936 uentry_mergeUses (uentry res, uentry other)
9938 llassert (uentry_isValid (res));
9939 llassert (uentry_isValid (other));
9941 res->used = other->used || res->used;
9942 res->lset = other->lset || res->lset;
9943 res->uses = filelocList_append (res->uses, other->uses);
9944 other->uses = filelocList_undefined;
9949 ** This is a really ugly routine.
9951 ** gack...fix this one day.
9956 ** >> res is the false branch, other is the true branch (or continuation)
9958 ** >> res is the true branch, other is the false branch (or continutation)
9965 ** References not effected by res are propagated from other.
9969 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9970 bool flip, clause cl, fileloc loc)
9974 message ("%s %q is %s %s, but %s %s.",
9975 ekind_capName (res->ukind), uentry_getName (res),
9976 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9977 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9980 if (sRef_isDead (res->sref))
9982 sRef_showStateInfo (res->sref);
9984 else if (sRef_isKept (res->sref))
9986 sRef_showAliasInfo (res->sref);
9988 else /* dependent */
9990 sRef_showAliasInfo (res->sref);
9991 sRef_showAliasInfo (other->sref);
9994 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9998 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10000 alkind rk = sRef_getAliasKind (rs);
10001 alkind ok = sRef_getAliasKind (os);
10003 if (alkind_isError (rk) || alkind_isError (ok))
10009 return ((sRef_isDead (rs)
10010 || (alkind_isKept (rk) && !alkind_isKept (ok))
10011 || (alkind_isDependent (rk)
10012 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10013 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10018 branchStateAltError (/*@notnull@*/ uentry res,
10019 /*@notnull@*/ uentry other, bool flip,
10020 clause cl, fileloc loc)
10024 message ("%s %q is %s %s, but %s %s.",
10025 ekind_capName (res->ukind), uentry_getName (res),
10026 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10027 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10030 if (sRef_isDead (other->sref))
10032 sRef_showStateInfo (other->sref);
10036 sRef_showAliasInfo (other->sref);
10039 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10040 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10042 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10043 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10048 ** A reference is relevant for certain checks, only if it
10049 ** is not definitely null on this path (but not declared
10050 ** to always be null.)
10053 static bool uentry_relevantReference (sRef sr, bool flip)
10055 if (sRef_isKept (sr) || sRef_isDependent (sr))
10063 return !sRef_definitelyNullContext (sr);
10067 return !sRef_definitelyNullAltContext (sr);
10073 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
10074 bool mustReturn, bool flip, bool opt,
10077 sRef rs = res->sref;
10078 sRef os = other->sref;
10080 DPRINTF (("Merge alias states: %s / %s",
10081 uentry_unparseFull (res),
10082 uentry_unparseFull (other)));
10084 if (sRef_isValid (rs))
10088 if (uentry_incompatibleMemoryStates (rs, os))
10090 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10091 sRef_unparseFull (rs), sRef_unparseFull (os)));
10093 if (sRef_isThroughArrayFetch (rs)
10094 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10096 if (sRef_isKept (rs) || sRef_isKept (os))
10098 sRef_maybeKill (rs, loc);
10100 else if (sRef_isPossiblyDead (os))
10102 sRef_maybeKill (rs, loc);
10111 if (uentry_relevantReference (os, flip))
10113 if (sRef_isLocalParamVar (rs)
10114 && (sRef_isLocalState (os)
10115 || sRef_isDependent (os)))
10117 if (sRef_isDependent (rs))
10119 sRef_setDependent (os, loc);
10123 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10128 branchStateError (res, other, flip, cl, loc);
10133 if (sRef_isKept (rs))
10135 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10136 sRef_setKept (os, loc);
10141 if (uentry_incompatibleMemoryStates (os, rs))
10143 if (uentry_relevantReference (rs, !flip))
10145 if (sRef_isLocalParamVar (rs)
10146 && (sRef_isDependent (rs)
10147 || sRef_isLocalState (rs)))
10149 if (sRef_isDependent (os))
10151 sRef_setDependent (rs, loc);
10155 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10160 if (sRef_isParam (os))
10163 ** If the local variable associated
10164 ** with the param has the correct state,
10166 ** (e.g., free (s); s = new(); ...
10169 uentry uvar = usymtab_lookupSafe (other->uname);
10171 if (uentry_isValid (uvar)
10172 && ((sRef_isDead (os)
10173 && sRef_isOnly (uvar->sref))
10174 || (sRef_isDependent (os)
10175 && sRef_isOwned (uvar->sref))))
10181 branchStateAltError (res, other,
10187 DPRINTF (("Here: %s / %s",
10188 uentry_unparseFull (res),
10189 uentry_unparseFull (other)));
10191 branchStateAltError (res, other,
10198 if (sRef_isKept (os))
10200 sRef_setKept (rs, loc);
10206 DPRINTF (("Merge opt..."));
10207 sRef_mergeOptState (rs, os, cl, loc);
10208 DPRINTF (("Done!"));
10212 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10213 sRef_mergeState (rs, os, cl, loc);
10214 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10219 if (sRef_isModified (os))
10221 sRef_setModified (rs);
10226 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10230 uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10232 valueTable rvalues;
10233 valueTable ovalues;
10235 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10243 rvalues = sRef_getValueTable (res->sref);
10244 ovalues = sRef_getValueTable (other->sref);
10246 if (valueTable_isUndefined (ovalues))
10248 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10251 else if (valueTable_isUndefined (rvalues))
10254 ** Copy values from other
10258 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10259 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10264 valueTable_elements (ovalues, fkey, fval) {
10266 metaStateInfo minfo;
10267 stateCombinationTable sctable;
10271 tval = valueTable_lookup (rvalues, fkey);
10273 DPRINTF (("Merge value: %s / %s X %s", fkey,
10274 stateValue_unparse (fval), stateValue_unparse (tval)));
10276 minfo = context_lookupMetaStateInfo (fkey);
10277 llassert (stateValue_isDefined (tval));
10279 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10281 DPRINTF (("Cannot find meta state for: %s", fkey));
10286 llassert (metaStateInfo_isDefined (minfo));
10288 if (stateValue_isError (fval)
10289 || sRef_definitelyNullContext (res->sref))
10291 sRef_setMetaStateValueComplete (res->sref,
10292 fkey, stateValue_getValue (fval),
10293 stateValue_getLoc (fval));
10294 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10296 else if (stateValue_isError (tval)
10297 || sRef_definitelyNullAltContext (other->sref))
10299 DPRINTF (("Other branch is definitely null!"));
10301 else if (sRef_isStateUndefined (res->sref)
10302 || sRef_isDead (res->sref))
10304 ; /* Combination state doesn't matter if it is undefined or dead */
10308 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10309 metaStateInfo_unparse (minfo),
10310 stateValue_unparse (fval),
10311 stateValue_unparse (tval)));
10313 DPRINTF (("state values: %d / %d",
10314 stateValue_getValue (fval), stateValue_getValue (tval)));
10316 sctable = metaStateInfo_getMergeTable (minfo);
10318 DPRINTF (("Merge table: %s",
10319 stateCombinationTable_unparse (sctable)));
10321 msg = cstring_undefined;
10323 nval = stateCombinationTable_lookup (sctable,
10324 stateValue_getValue (fval),
10325 stateValue_getValue (tval),
10328 DPRINTF (("nval: %d / %d / %d", nval,
10329 stateValue_getValue (fval), stateValue_getValue (tval)));
10331 if (nval == stateValue_error)
10333 /*@i32 print extra info for assignments@*/
10335 if (uentry_isGlobalMarker (res))
10340 ("Control branches merge with incompatible global states (%s and %s)%q",
10341 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10342 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10343 cstring_isDefined (msg)
10344 ? message (": %s", msg) : cstring_undefined),
10347 sRef_showMetaStateInfo (res->sref, fkey);
10348 sRef_showMetaStateInfo (other->sref, fkey);
10356 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10357 uentry_getName (res),
10358 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10359 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10360 cstring_isDefined (msg)
10361 ? message (": %s", msg) : cstring_undefined),
10364 sRef_showMetaStateInfo (res->sref, fkey);
10365 sRef_showMetaStateInfo (other->sref, fkey);
10366 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10367 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10368 DPRINTF (("Null: %s / %s",
10369 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10370 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10376 if (nval == stateValue_getValue (fval)
10377 && nval != stateValue_getValue (tval))
10379 loc = stateValue_getLoc (fval);
10381 else if (nval == stateValue_getValue (tval)
10382 && nval != stateValue_getValue (fval))
10384 loc = stateValue_getLoc (tval);
10391 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10392 && nval == stateValue_getValue (fval)
10393 && nval == stateValue_getValue (tval))
10399 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10403 } end_valueTable_elements ;
10409 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10410 bool flip, clause cl)
10412 if (cl == DOWHILECLAUSE)
10414 res->used = other->used || res->used;
10415 res->lset = other->lset || res->lset;
10416 res->uses = filelocList_append (res->uses, other->uses);
10417 other->uses = filelocList_undefined;
10421 if (sRef_isMacroParamRef (res->sref)
10422 && !uentry_isSefParam (other)
10423 && !uentry_isSefParam (res))
10425 bool hasError = FALSE;
10427 if (bool_equal (res->used, other->used))
10429 res->used = other->used;
10433 if (other->used && !flip)
10438 message ("Macro parameter %q used in true clause, "
10439 "but not in false clause",
10440 uentry_getName (res)),
10441 uentry_whereDeclared (res));
10448 message ("Macro parameter %q used in false clause, "
10449 "but not in true clause",
10450 uentry_getName (res)),
10451 uentry_whereDeclared (res));
10457 /* make it sef now, prevent more errors */
10458 res->info->var->kind = VKREFSEFPARAM;
10464 res->used = other->used || res->used;
10465 res->lset = other->lset || res->lset;
10466 res->uses = filelocList_append (res->uses, other->uses);
10467 other->uses = filelocList_undefined;
10473 uentry_mergeState (uentry res, uentry other, fileloc loc,
10474 bool mustReturn, bool flip, bool opt,
10477 llassert (uentry_isValid (res));
10478 llassert (uentry_isValid (other));
10480 llassert (res->ukind == other->ukind);
10481 llassert (res->ukind == KVAR);
10483 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10484 uentry_unparseFull (other)));
10486 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10487 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10488 uentry_mergeSetStates (res, other, loc, flip, cl);
10490 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10493 void uentry_setUsed (uentry e, fileloc loc)
10495 static bool firstTime = TRUE;
10496 static bool showUses = FALSE;
10497 static bool exportLocal = FALSE;
10499 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10503 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10505 showUses = context_getFlag (FLG_SHOWUSES);
10506 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10511 if (uentry_isValid (e))
10515 if (warnClause_isDefined (e->warn))
10517 flagSpec flg = warnClause_getFlag (e->warn);
10520 if (warnClause_hasMessage (e->warn))
10522 msg = cstring_copy (warnClause_getMessage (e->warn));
10526 msg = message ("Use of possibly dangerous %s",
10527 uentry_ekindNameLC (e));
10531 message ("%q: %q", msg, uentry_getName (e)),
10535 if (sRef_isMacroParamRef (e->sref))
10537 if (uentry_isYield (e) || uentry_isSefParam (e))
10543 if (context_inConditional ())
10547 message ("Macro parameter %q used in conditionally "
10548 "executed code (may or may not be "
10549 "evaluated exactly once)",
10550 uentry_getName (e)),
10553 e->info->var->kind = VKREFSEFPARAM;
10562 message ("Macro parameter %q used more than once",
10563 uentry_getName (e)),
10564 uentry_whereDeclared (e)))
10566 e->info->var->kind = VKREFSEFPARAM;
10573 if ((dp = uentry_directParamNo (e)) >= 0)
10575 uentry_setUsed (usymtab_getParam (dp), loc);
10580 if (!sRef_isLocalVar (e->sref))
10584 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10590 if (context_inMacro ())
10592 e->uses = filelocList_addUndefined (e->uses);
10596 e->uses = filelocList_addDifferentFile
10598 uentry_whereDeclared (e),
10607 bool uentry_isReturned (uentry u)
10609 return (uentry_isValid (u) && uentry_isVar (u)
10610 && (u->info->var->kind == VKRETPARAM
10611 || u->info->var->kind == VKSEFRETPARAM));
10614 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10616 llassert (uentry_isRealFunction (u));
10618 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10620 stateClauseList clauses = uentry_getStateClauseList (u);
10621 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10623 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10624 sRef_setAllocated (res, g_currentloc);
10626 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10627 stateClauseList_unparse (clauses)));
10630 ** This should be in exprNode_reflectEnsuresClause
10633 stateClauseList_postElements (clauses, cl)
10635 if (!stateClause_isGlobal (cl))
10637 sRefSet refs = stateClause_getRefs (cl);
10638 sRefMod modf = stateClause_getEffectFunction (cl);
10640 sRefSet_elements (refs, el)
10642 sRef base = sRef_getRootBase (el);
10644 if (sRef_isResult (base))
10648 sRef sr = sRef_fixBase (el, res);
10649 modf (sr, g_currentloc);
10656 } end_sRefSet_elements ;
10658 } end_stateClauseList_postElements ;
10666 sRefSet prefs = sRefSet_new ();
10667 sRef res = sRef_undefined;
10670 params = uentry_getParams (u);
10672 uentryList_elements (params, current)
10674 if (uentry_isReturned (current))
10676 if (exprNodeList_size (args) >= paramno)
10678 exprNode ecur = exprNodeList_nth (args, paramno);
10679 sRef tref = exprNode_getSref (ecur);
10681 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10683 if (sRef_isValid (tref))
10685 sRef tcref = sRef_copy (tref);
10687 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10689 if (sRef_isDead (tcref))
10691 sRef_setDefined (tcref, g_currentloc);
10692 sRef_setOnly (tcref, g_currentloc);
10695 if (sRef_isRefCounted (tcref))
10697 /* could be a new ref now (but only if its returned) */
10698 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10701 sRef_makeSafe (tcref);
10702 prefs = sRefSet_insert (prefs, tcref);
10708 } end_uentryList_elements ;
10710 if (sRefSet_size (prefs) > 0)
10712 nstate n = sRef_getNullState (u->sref);
10714 if (sRefSet_size (prefs) == 1)
10716 res = sRefSet_choose (prefs);
10720 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10721 res = sRefSet_mergeIntoOne (prefs);
10724 if (nstate_isKnown (n))
10726 sRef_setNullState (res, n, g_currentloc);
10731 if (ctype_isFunction (u->utype))
10733 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10734 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10738 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10741 if (sRef_isRefCounted (res))
10743 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10748 if (sRef_getNullState (res) == NS_ABSNULL)
10750 ctype ct = ctype_realType (u->utype);
10752 if (ctype_isAbstract (ct))
10754 sRef_setNotNull (res, g_currentloc);
10758 if (ctype_isUser (ct))
10760 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10764 sRef_setNotNull (res, g_currentloc);
10769 if (sRef_isRefCounted (res))
10771 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10773 else if (sRef_isKillRef (res))
10775 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10782 ak = sRef_getAliasKind (res);
10784 if (alkind_isImplicit (ak))
10786 sRef_setAliasKind (res,
10787 alkind_fixImplicit (ak),
10791 sRefSet_free (prefs);
10793 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10798 static bool uentry_isRefCounted (uentry ue)
10800 ctype ct = uentry_getType (ue);
10802 if (ctype_isFunction (ct))
10804 return (ctype_isRefCounted (ctype_getReturnType (ct)));
10808 return (ctype_isRefCounted (ct));
10813 ** old was declared yield in the specification.
10814 ** new is declared in the iter implementation.
10817 void uentry_checkYieldParam (uentry old, uentry unew)
10821 llassert (uentry_isVariable (old));
10822 llassert (uentry_isVariable (unew));
10824 unew->info->var->kind = VKYIELDPARAM;
10825 (void) checkTypeConformance (old, unew, TRUE);
10826 checkVarConformance (old, unew, TRUE, FALSE);
10828 /* get rid of param marker */
10830 name = uentry_getName (unew);
10831 cstring_free (unew->uname);
10832 unew->uname = name;
10833 unew->info->var->kind = VKREFYIELDPARAM;
10835 uentry_setUsed (old, fileloc_undefined);
10836 uentry_setUsed (unew, fileloc_undefined);
10839 /*@observer@*/ cstring
10840 uentry_ekindName (uentry ue)
10842 if (uentry_isValid (ue))
10847 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10849 return cstring_makeLiteralTemp ("Datatype");
10851 return cstring_makeLiteralTemp ("Enum member");
10853 return cstring_makeLiteralTemp ("Constant");
10855 if (uentry_isParam (ue))
10857 return cstring_makeLiteralTemp ("Parameter");
10859 else if (uentry_isExpandedMacro (ue))
10861 return cstring_makeLiteralTemp ("Expanded macro");
10865 return cstring_makeLiteralTemp ("Variable");
10868 return cstring_makeLiteralTemp ("Function");
10870 return cstring_makeLiteralTemp ("Iterator");
10872 return cstring_makeLiteralTemp ("Iterator finalizer");
10874 return cstring_makeLiteralTemp ("Struct tag");
10876 return cstring_makeLiteralTemp ("Union tag");
10878 return cstring_makeLiteralTemp ("Enum tag");
10880 return cstring_makeLiteralTemp ("Optional parameters");
10885 return cstring_makeLiteralTemp ("<Undefined>");
10891 /*@observer@*/ cstring
10892 uentry_ekindNameLC (uentry ue)
10894 if (uentry_isValid (ue))
10899 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10901 return cstring_makeLiteralTemp ("datatype");
10903 return cstring_makeLiteralTemp ("enum member");
10905 return cstring_makeLiteralTemp ("constant");
10907 if (uentry_isParam (ue))
10909 return cstring_makeLiteralTemp ("parameter");
10911 else if (uentry_isExpandedMacro (ue))
10913 return cstring_makeLiteralTemp ("expanded macro");
10917 return cstring_makeLiteralTemp ("variable");
10920 return cstring_makeLiteralTemp ("function");
10922 return cstring_makeLiteralTemp ("iterator");
10924 return cstring_makeLiteralTemp ("iterator finalizer");
10926 return cstring_makeLiteralTemp ("struct tag");
10928 return cstring_makeLiteralTemp ("union tag");
10930 return cstring_makeLiteralTemp ("enum tag");
10932 return cstring_makeLiteralTemp ("optional parameters");
10937 return cstring_makeLiteralTemp ("<Undefined>");
10943 void uentry_setHasNameError (uentry ue)
10945 llassert (uentry_isValid (ue));
10947 ue->hasNameError = TRUE;
10950 void uentry_checkName (uentry ue)
10952 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10953 uentry_observeRealName (ue),
10954 bool_unparse (uentry_isVisibleExternally (ue))));
10956 if (uentry_isValid (ue)
10957 && !context_inXHFile ()
10958 && uentry_hasName (ue)
10959 && !uentry_isElipsisMarker (ue)
10960 && context_getFlag (FLG_NAMECHECKS)
10961 && !ue->hasNameError
10962 && !uentry_isEndIter (ue)
10963 && !fileloc_isBuiltin (uentry_whereLast (ue))
10964 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10966 DPRINTF (("Here..."));
10968 if (uentry_isPriv (ue))
10970 ; /* any checks here? */
10972 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10974 ; /* no errors for externals */
10980 if (uentry_isExpandedMacro (ue))
10986 if (uentry_isExpandedMacro (ue))
10990 else if (uentry_isVariable (ue))
10992 sRef sr = uentry_getSref (ue);
10994 if (sRef_isValid (sr))
10996 scope = sRef_getScope (sr);
11003 else if (uentry_isFunction (ue)
11004 || uentry_isIter (ue)
11005 || uentry_isEndIter (ue)
11006 || uentry_isConstant (ue))
11008 scope = uentry_isStatic (ue) ? fileScope : globScope;
11010 else /* datatypes, etc. must be global */
11015 usymtab_checkDistinctName (ue, scope);
11018 if (context_getFlag (FLG_CPPNAMES))
11023 if (scope == globScope)
11025 checkExternalName (ue);
11027 else if (scope == fileScope)
11029 checkFileScopeName (ue);
11033 checkLocalName (ue);
11037 checkAnsiName (ue);
11042 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11048 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11051 if (!context_inMacro ())
11053 sRef_setGlobalScopeSafe ();
11056 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11057 uentry_setUsed (ue, loc);
11059 tloc = fileloc_createExternal ();
11060 uentry_setDefined (ue, tloc);
11061 fileloc_free (tloc);
11062 uentry_setHasNameError (ue);
11064 if (context_getFlag (FLG_REPEATUNRECOG))
11066 uentry_markOwned (ue);
11070 ue = usymtab_supReturnFileEntry (ue);
11073 if (!context_inMacro ())
11075 sRef_clearGlobalScopeSafe ();
11081 uentry uentry_makeGlobalMarker ()
11086 llassert (sRef_inGlobalScope ());
11088 ue = uentry_makeVariableAux
11089 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11090 sRef_makeGlobalMarker (),
11093 tloc = fileloc_createExternal ();
11094 uentry_setUsed (ue, tloc);
11095 uentry_setDefined (ue, tloc);
11096 fileloc_free (tloc);
11097 uentry_setHasNameError (ue);
11103 bool uentry_isGlobalMarker (uentry ue)
11105 return (uentry_isValid (ue)
11106 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11109 /* new start modifications */
11111 /* start modifications */
11113 requires: p_e is defined, is a ptr/array variable
11115 effects: sets the state of the variable
11119 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
11120 /*@access sRef@*/ /*i523 shouldn't do this! */
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_POSSIBLYNULLTERMINATED;
11125 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11130 /*@noaccess sRef@*/
11132 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11136 requires: p_e is defined, is a ptr/array variable
11138 effects: sets the size of the buffer
11141 void uentry_setNullTerminatedState (uentry p_e) {
11142 if( uentry_isValid(p_e) ) {
11143 if( p_e->info != NULL) {
11144 if( p_e->info->var != NULL) {
11145 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11146 /*@access sRef@*/ /*@i523 bad!*/
11147 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11148 /*@noaccess sRef@*/
11154 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11158 requires: p_e is defined, is a ptr/array variable
11160 effects: sets the size of the buffer
11163 void uentry_setSize (uentry p_e, int size) {
11164 if( uentry_isValid(p_e) ) {
11165 if( p_e->info != NULL) {
11166 if( p_e->info->var != NULL) {
11167 p_e->info->var->bufinfo->size = size;
11168 /*@access sRef@*/ /*@i523 bad!*/
11169 p_e->sref->bufinfo.size = size;
11170 /*@noaccess sRef@*/
11176 fprintf(stderr, "uentry:Error in setSize\n");
11181 requires: p_e is defined, is a ptr/array variable
11183 effects: sets the length of the buffer
11186 void uentry_setLen (uentry p_e, int len) {
11187 if( uentry_isValid(p_e) ) {
11188 if( p_e->info != NULL) {
11189 if( p_e->info->var != NULL) {
11190 p_e->info->var->bufinfo->len = len;
11191 /*@access sRef@*/ /*@i523 bad!*/
11192 p_e->sref->bufinfo.len = len;
11193 /*@noaccess sRef@*/
11199 fprintf(stderr, "uentry:Error in setLen\n");
11204 bool uentry_hasMetaStateEnsures (uentry e)
11206 if (uentry_isValid (e) && uentry_isFunction (e))
11208 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11216 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11218 llassert (uentry_isValid (e) && uentry_isFunction (e));
11219 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);