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_warningstream@*/ ;
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_warningstream@*/ ;
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))
1449 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1450 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1451 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1455 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1458 ** Okay to allow multiple clauses of the same kind.
1459 */ /*@i834 is this true?@*/
1461 ue->info->fcn->specclauses =
1462 stateClauseList_add (ue->info->fcn->specclauses, sc);
1464 /* Will call checkAll to check later... */
1467 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1469 llassert (uentry_isFunction (ue));
1470 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1472 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1473 ue->info->fcn->specclauses = clauses;
1474 stateClauseList_checkAll (ue);
1475 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1479 ** Used for @modifies@ @endmodifies@ syntax.
1481 ** If ue is specified, sr must contain *only*:
1483 ** o file static globals
1484 ** o sRef's derived from modifies spec (i.e., more specific than
1485 ** what was specified)
1487 ** Otherwise, if sr has modifies it must match sr.
1489 ** If it doesn't have modifies, set them to sr.
1493 uentry_checkModifiesContext (void)
1495 if (sRef_modInFunction ())
1499 ("Modifies list not in function context. "
1500 "A modifies list can only appear following the parameter list "
1501 "in a function declaration or header."));
1510 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1512 if (!uentry_checkModifiesContext ())
1518 if (uentry_isValid (ue))
1520 if (uentry_isIter (ue))
1522 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1523 ue->info->iter->mods = sr;
1527 uentry_convertVarFunction (ue);
1528 llassertfatal (uentry_isFunction (ue));
1529 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1531 ue->info->fcn->mods = sr;
1532 ue->info->fcn->hasMods = TRUE;
1534 checkGlobalsModifies (ue, sr);
1537 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1539 ue->info->fcn->hasGlobs = TRUE;
1542 if (sRefSet_hasStatic (ue->info->fcn->mods))
1544 context_recordFileModifies (ue->info->fcn->mods);
1554 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1557 ** Function already has one modifies clause (possibly from
1558 ** a specification).
1561 if (!uentry_checkModifiesContext ())
1566 llassert (uentry_isValid (ue));
1568 if (uentry_isIter (ue))
1570 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1574 llassertfatal (uentry_isFunction (ue));
1575 llassert (ue->info->fcn->hasMods);
1577 checkGlobalsModifies (ue, sr);
1578 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1580 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1582 ue->info->fcn->hasGlobs = TRUE;
1586 if (sRefSet_hasStatic (ue->info->fcn->mods))
1588 context_recordFileModifies (ue->info->fcn->mods);
1592 bool uentry_hasWarning (uentry ue)
1594 return (uentry_isValid (ue)
1595 && warnClause_isDefined (ue->warn));
1598 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1600 llassert (uentry_isValid (ue));
1601 llassert (warnClause_isUndefined (ue->warn));
1606 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1608 if (sRef_modInFunction ())
1611 (message ("Precondition list not in function context. "
1612 "A precondition list can only appear following the parameter list "
1613 "in a function declaration or header."));
1615 /*@-mustfree@*/ return; /*@=mustfree@*/
1618 if (uentry_isValid (ue))
1620 uentry_convertVarFunction (ue);
1621 llassertfatal (uentry_isFunction (ue));
1623 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1626 I changed this so it didn't appear as a Splint bug
1627 among other things this gets triggered when there is
1628 a function with two requires clauses. Now Splint
1629 prints an error and tries to conjoin the lists.
1632 (message ("Duplicate precondition list"
1633 "Attemping the conjoin the requires clauses"
1637 /* should conjoin constraints? */
1639 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1643 ue->info->fcn->preconditions = preconditions;
1648 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1657 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1659 if (sRef_modInFunction ())
1662 (message ("Postcondition list not in function context. "
1663 "A postcondition list can only appear following the parameter list "
1664 "in a function declaration or header."));
1666 /*@-mustfree@*/ return; /*@=mustfree@*/
1669 if (uentry_isValid (ue))
1671 uentry_convertVarFunction (ue);
1672 llassertfatal (uentry_isFunction (ue));
1674 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1676 ue->info->fcn->postconditions = postconditions;
1680 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1685 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1690 ** requires: new and old are functions
1694 checkGlobalsConformance (/*@notnull@*/ uentry old,
1695 /*@notnull@*/ uentry unew,
1696 bool mustConform, bool completeConform)
1698 bool hasInternalState = FALSE;
1700 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1702 if (globSet_isDefined (unew->info->fcn->globs))
1704 globSet_allElements (unew->info->fcn->globs, el)
1706 if (sRef_isFileStatic (el))
1708 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1710 if (sRef_isInvalid (sr))
1712 bool hasError = FALSE;
1714 if (!hasInternalState
1715 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1716 sRef_makeInternalState ()))
1717 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1718 sRef_makeSpecState ())))
1721 && !uentry_isStatic (old)
1724 message ("Globals list for %q includes internal state, %q, "
1725 "but %s without globals internalState.",
1726 uentry_getName (old),
1728 uentry_specOrDefName (old)),
1729 uentry_whereLast (unew)))
1731 uentry_showWhereSpecified (old);
1735 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1736 sRef_makeInternalState ());
1737 hasInternalState = TRUE;
1741 && fileloc_sameFile (uentry_whereDeclared (unew),
1742 uentry_whereDeclared (old)))
1747 message ("Function %q inconsistently %rdeclared (in "
1748 "same file) with file static global %q in "
1750 uentry_getName (unew),
1751 uentry_isDeclared (old),
1753 uentry_whereDeclared (unew)))
1755 uentry_showWhereSpecified (old);
1760 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1761 context_recordFileGlobals (old->info->fcn->globs);
1765 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1767 if (sRef_isInvalid (sr))
1772 message ("Function %q inconsistently %rdeclared with "
1773 "%q in globals list",
1774 uentry_getName (unew),
1775 uentry_isDeclared (old),
1777 uentry_whereDeclared (unew)))
1779 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1780 uentry_showWhereSpecified (old);
1785 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1791 ("Function %q global %q inconsistently "
1792 "%rdeclared as %qout global",
1793 uentry_getName (unew),
1795 uentry_isDeclared (old),
1796 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1797 uentry_whereDeclared (unew)))
1799 uentry_showWhereSpecified (old);
1804 } end_globSet_allElements ;
1806 if (completeConform)
1808 globSet_allElements (old->info->fcn->globs, el)
1810 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1812 if (sRef_isInvalid (sr))
1815 && uentry_isReallySpecified (old)
1818 message ("Function %q specified with %q in globals list, "
1819 "but declared without %q",
1820 uentry_getName (unew),
1823 uentry_whereDeclared (unew)))
1825 uentry_showWhereSpecified (old);
1828 } end_globSet_allElements;
1833 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1835 if (uentry_isReallySpecified (old)
1838 message ("%s %q specified with globals list, but "
1839 "declared with no globals",
1840 ekind_capName (unew->ukind),
1841 uentry_getName (unew)),
1842 uentry_whereDeclared (unew)))
1845 (message ("Specification globals: %q",
1846 globSet_unparse (old->info->fcn->globs)),
1847 uentry_whereSpecified (old));
1851 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1852 old->info->fcn->globs);
1857 ** new modifies list must be included by old modifies list.
1859 ** file static state may be added to new, if old has internal.
1863 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1864 bool mustConform, bool completeConform)
1867 bool changedMods = FALSE;
1868 bool modInternal = FALSE;
1870 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1872 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1873 newMods = unew->info->fcn->mods;
1875 if (sRefSet_isEmpty (newMods))
1877 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1878 && uentry_isReallySpecified (old))
1882 message ("%s %q specified with modifies clause, "
1883 "but declared with no modifies clause",
1884 ekind_capName (unew->ukind),
1885 uentry_getName (unew)),
1886 uentry_whereDeclared (unew)))
1888 llgenindentmsg (message ("Specification has modifies %q",
1889 sRefSet_unparse (old->info->fcn->mods)),
1890 uentry_whereSpecified (old));
1897 sRefSet_allElements (newMods, current)
1899 if (sRef_isValid (current))
1901 sRef rb = sRef_getRootBase (current);
1903 if (sRef_isFileStatic (rb))
1907 if (!sRefSet_isSameMember (old->info->fcn->mods,
1908 sRef_makeInternalState ())
1909 && !sRefSet_isSameMember (old->info->fcn->mods,
1910 sRef_makeSpecState ()))
1913 && !uentry_isStatic (old)
1917 ("Modifies list for %q includes internal state, "
1918 "but %s without modifies internal.",
1919 uentry_getName (old),
1920 uentry_specOrDefName (old)),
1921 uentry_whereLast (unew)))
1923 uentry_showWhereSpecified (old);
1926 old->info->fcn->mods =
1927 sRefSet_insert (old->info->fcn->mods,
1928 sRef_makeInternalState ());
1933 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1939 if (sRef_canModifyVal (current, old->info->fcn->mods))
1941 int size = sRefSet_size (old->info->fcn->mods);
1943 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1946 if (sRefSet_size (old->info->fcn->mods) != size)
1957 ("Modifies list for %q contains %q, not modifiable "
1959 uentry_getName (old),
1960 sRef_unparse (current),
1961 uentry_specDeclName (old)),
1962 uentry_whereLast (unew)))
1964 uentry_showWhereSpecified (old);
1969 } end_sRefSet_allElements;
1971 if (completeConform && uentry_isReallySpecified (old))
1973 sRefSet_allElements (old->info->fcn->mods, el)
1975 if (sRef_canModify (el, newMods))
1984 ("Specification modifies clause for %q contains %q, "
1985 "not included in declaration modifies clause",
1986 uentry_getName (old),
1988 uentry_whereLast (unew)))
1990 uentry_showWhereSpecified (old);
1993 } end_sRefSet_allElements ;
1997 ** Make sure file static elements will be removed.
2002 context_recordFileModifies (old->info->fcn->mods);
2007 uentry_checkMutableType (uentry ue)
2009 ctype ct = uentry_getType (ue);
2011 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2013 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2015 voptgenerror (FLG_MUTREP,
2016 message ("Mutable abstract type %q declared without pointer "
2017 "indirection: %t (violates assignment semantics)",
2018 uentry_getName (ue), ct),
2019 uentry_whereDeclared (ue));
2024 uentry_setMutable (uentry e)
2026 llassert (uentry_isDatatype (e));
2027 e->info->datatype->mut = YES;
2031 uentry_checkIterArgs (uentry ue)
2033 bool hasYield = FALSE;
2036 llassert (uentry_isIter (ue));
2038 args = uentry_getParams (ue);
2040 uentryList_elements (args, el)
2042 sstate ds = uentry_getDefState (el);
2044 if (uentry_isYield (el))
2049 if (sstate_isUnknown (ds))
2051 uentry_setDefState (el, SS_DEFINED);
2057 } end_uentryList_elements;
2061 voptgenerror (FLG_HASYIELD,
2062 message ("Iterator %q declared with no yield parameters",
2063 uentry_getName (ue)),
2064 uentry_whereDeclared (ue));
2069 chkind_fromQual (qual qel)
2071 if (qual_isChecked (qel))
2075 else if (qual_isCheckMod (qel))
2079 else if (qual_isCheckedStrict (qel))
2081 return CH_CHECKEDSTRICT;
2083 else if (qual_isUnchecked (qel))
2085 return CH_UNCHECKED;
2090 /*@notreached@*/ return CH_UNKNOWN;
2095 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2097 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2099 if (!uentry_isRefCounted (ue))
2102 (FLG_ANNOTATIONERROR,
2103 message ("Reference counting qualifier %s used on non-reference "
2104 "counted storage: %q",
2106 uentry_unparse (ue)),
2107 uentry_whereLast (ue));
2111 alkind ak = alkind_fromQual (qel);
2113 uentry_setAliasKind (ue, ak);
2116 else if (qual_isRefCounted (qel))
2118 ctype ct = ctype_realType (uentry_getType (ue));
2121 if (ctype_isPointer (ct)
2122 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2124 /* check there is a refs field */
2125 uentryList fields = ctype_getFields (rt);
2126 uentry refs = uentry_undefined;
2128 uentryList_elements (fields, field)
2130 if (uentry_isRefsField (field))
2132 if (uentry_isValid (refs))
2135 (FLG_ANNOTATIONERROR,
2136 message ("Reference counted structure type %s has "
2137 "multiple refs fields: %q and %q",
2139 uentry_getName (refs),
2140 uentry_getName (field)),
2141 uentry_whereLast (field));
2146 } end_uentryList_elements;
2148 if (uentry_isInvalid (refs))
2152 message ("Reference counted structure type %s has "
2154 ctype_unparse (ct)),
2156 ("To count reference, the structure must have a field named "
2157 "refs of type int."),
2160 else if (!ctype_isInt (uentry_getType (refs)))
2163 (FLG_ANNOTATIONERROR,
2164 message ("Reference counted structure type %s refs field has "
2165 "type %s (should be int)", ctype_unparse (ct),
2166 ctype_unparse (uentry_getType (refs))),
2167 uentry_whereLast (refs));
2171 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2172 uentry_whereDeclared (ue));
2177 if ((ctype_isPointer (ct)
2178 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2179 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2181 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2182 uentry_whereDeclared (ue));
2187 (FLG_ANNOTATIONERROR,
2188 message ("Non-pointer to structure type %s declared with "
2189 "refcounted qualifier",
2190 ctype_unparse (ct)),
2191 uentry_whereLast (ue));
2195 else if (qual_isRefs (qel))
2197 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2199 uentry_setAliasKind (ue, AK_REFS);
2204 (FLG_ANNOTATIONERROR,
2205 message ("Refs qualifier used on non-structure field: %q",
2206 uentry_unparse (ue)),
2207 uentry_whereLast (ue));
2210 else if (qual_isAliasQual (qel))
2212 alkind ak = alkind_fromQual (qel);
2214 alkind oldak = uentry_getAliasKind (ue);
2215 ctype ut = uentry_getType (ue);
2217 if (alkind_isImplicit (ak)
2218 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2220 /* ignore the implied qualifier */
2224 if (uentry_isEitherConstant (ue))
2227 (FLG_ANNOTATIONERROR,
2228 message ("Alias qualifier %s used on constant: %q",
2229 alkind_unparse (ak), uentry_unparse (ue)),
2230 uentry_whereLast (ue));
2235 if (ctype_isFunction (ut))
2237 ut = ctype_getReturnType (ut);
2240 if (!(ctype_isVisiblySharable (ut)
2241 || ctype_isRealArray (ut)
2242 || ctype_isRealSU (ut)))
2244 if (!qual_isImplied (qel))
2247 (FLG_ANNOTATIONERROR,
2248 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2249 alkind_unparse (ak), ut, uentry_getName (ue)),
2250 uentry_whereLast (ue));
2257 if (uentry_isRefCounted (ue))
2259 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2260 || qual_isExposed (qel)
2261 || qual_isObserver (qel)))
2263 if (!qual_isImplied (qel))
2266 (FLG_ANNOTATIONERROR,
2268 ("Alias qualifier %s used on reference counted storage: %q",
2269 alkind_unparse (ak),
2270 uentry_unparse (ue)),
2271 uentry_whereLast (ue));
2279 if (qual_isRefQual (qel))
2282 (FLG_ANNOTATIONERROR,
2283 message ("Qualifier %s used on non-reference counted storage: %q",
2284 alkind_unparse (ak), uentry_unparse (ue)),
2285 uentry_whereLast (ue));
2294 uentry_setAliasKind (ue, ak);
2297 else if (qual_isNull (qel))
2299 if (uentry_isConstant (ue))
2303 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2304 uentry_whereDeclared (ue));
2308 uentry_setNullState (ue, NS_POSNULL);
2311 else if (qual_isRelNull (qel))
2313 uentry_setNullState (ue, NS_RELNULL);
2315 else if (qual_isNotNull (qel))
2317 uentry_setNullState (ue, NS_MNOTNULL);
2319 else if (qual_isAbstract (qel)
2320 || qual_isConcrete (qel))
2322 if (!uentry_isDatatype (ue))
2325 (FLG_ANNOTATIONERROR,
2326 message ("Qualifier %s used with non-datatype",
2327 qual_unparse (qel)),
2328 uentry_whereLast (ue));
2332 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2335 else if (qual_isMutable (qel))
2337 if (!uentry_isDatatype (ue))
2340 (FLG_ANNOTATIONERROR,
2341 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2342 uentry_whereLast (ue));
2346 if (!ynm_isOn (ue->info->datatype->mut))
2348 uentry_checkMutableType (ue);
2351 ue->info->datatype->mut = YES;
2354 else if (qual_isImmutable (qel))
2356 if (!uentry_isDatatype (ue))
2358 voptgenerror (FLG_ANNOTATIONERROR,
2359 message ("Qualifier %s used with non-datatype",
2360 qual_unparse (qel)),
2361 uentry_whereLast (ue));
2365 ue->info->datatype->mut = NO;
2368 else if (qual_isNullPred (qel))
2370 uentry_convertVarFunction (ue);
2372 if (uentry_isFunction (ue))
2374 ctype typ = uentry_getType (ue);
2375 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2377 if (ctype_isRealBool (rtype))
2379 uentryList pl = ctype_argsFunction (typ);
2381 if (uentryList_size (pl) == 1)
2383 ue->info->fcn->nullPred = qel;
2387 voptgenerror (FLG_ANNOTATIONERROR,
2388 message ("Qualifier %s used with function having %d "
2389 "arguments (should have 1)",
2391 uentryList_size (pl)),
2392 uentry_whereLast (ue));
2397 voptgenerror (FLG_ANNOTATIONERROR,
2398 message ("Qualifier %s used with function returning %s "
2399 "(should return bool)",
2401 ctype_unparse (rtype)),
2402 uentry_whereLast (ue));
2407 voptgenerror (FLG_ANNOTATIONERROR,
2408 message ("Qualifier %s used with non-function",
2409 qual_unparse (qel)),
2410 uentry_whereLast (ue));
2413 else if (qual_isExitQual (qel))
2415 exitkind exk = exitkind_fromQual (qel);
2417 if (uentry_isFunction (ue))
2419 if (exitkind_isKnown (ue->info->fcn->exitCode))
2421 voptgenerror (FLG_ANNOTATIONERROR,
2422 message ("Multiple exit qualifiers used on function %q: %s, %s",
2423 uentry_getName (ue),
2424 exitkind_unparse (ue->info->fcn->exitCode),
2425 exitkind_unparse (exk)),
2426 uentry_whereLast (ue));
2429 ue->info->fcn->exitCode = exk;
2433 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2435 uentry_makeVarFunction (ue);
2436 ue->info->fcn->exitCode = exk;
2440 voptgenerror (FLG_ANNOTATIONERROR,
2441 message ("Exit qualifier %s used with non-function (type %s)",
2443 ctype_unparse (uentry_getType (ue))),
2444 uentry_whereLast (ue));
2448 else if (qual_isMetaState (qel))
2450 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2452 if (annotationInfo_matchesContext (ainfo, ue))
2454 DPRINTF (("Reflecting %s on %s",
2455 annotationInfo_unparse (ainfo),
2456 uentry_unparseFull (ue)));
2458 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2459 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2460 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2465 (FLG_ANNOTATIONERROR,
2466 message ("Attribute annotation %s used in inconsistent context: %q",
2468 uentry_unparse (ue)),
2469 uentry_whereLast (ue)))
2471 /*@i! annotationInfo_showContextError (ainfo, ue); */
2477 if (qual_isCQual (qel))
2483 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2489 uentry_reflectQualifiers (uentry ue, qualList q)
2491 llassert (uentry_isValid (ue));
2493 DPRINTF (("Reflect qualifiers: %s / %s",
2494 uentry_unparseFull (ue), qualList_unparse (q)));
2496 qualList_elements (q, qel)
2498 if (qual_isStatic (qel))
2500 uentry_setStatic (ue);
2502 else if (qual_isUnused (qel))
2504 uentry_setUsed (ue, fileloc_undefined);
2505 DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2507 else if (qual_isExternal (qel))
2509 fileloc_free (ue->whereDefined);
2510 ue->whereDefined = fileloc_createExternal ();
2512 else if (qual_isSef (qel))
2514 if (uentry_isVariable (ue))
2516 vkind vk = ue->info->var->kind;
2518 llassert (vk != VKREFPARAM);
2520 if (vk == VKYIELDPARAM)
2523 (FLG_ANNOTATIONERROR,
2524 message ("Qualifier sef cannot be used with %s: %q",
2525 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2526 uentry_unparse (ue)),
2527 uentry_whereLast (ue));
2529 else if (vk == VKRETPARAM)
2531 ue->info->var->kind = VKSEFRETPARAM;
2535 ue->info->var->kind = VKSEFPARAM;
2541 (FLG_ANNOTATIONERROR,
2542 message ("Qualifier sef is meaningful only on parameters: %q",
2543 uentry_unparse (ue)),
2544 uentry_whereLast (ue));
2547 else if (qual_isExtern (qel))
2549 ue->storageclass = SCEXTERN;
2551 else if (qual_isGlobalQual (qel)) /* undef, killed */
2553 DPRINTF (("Reflecting qual: %s / %s",
2554 qual_unparse (qel), uentry_unparse (ue)));
2556 if (uentry_isVariable (ue))
2558 sstate oldstate = ue->info->var->defstate;
2559 sstate defstate = sstate_fromQual (qel);
2562 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2563 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2565 defstate = SS_UNDEFKILLED;
2572 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2573 ue->info->var->defstate = defstate;
2578 (FLG_ANNOTATIONERROR,
2579 message ("Qualifier %s used on non-variable: %q",
2580 qual_unparse (qel), uentry_unparse (ue)),
2581 uentry_whereLast (ue));
2584 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2586 /* start modifications */
2587 else if( qual_isBufQualifier(qel) ) {
2588 ctype ct = ctype_realType(uentry_getType(ue));
2589 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2591 if( uentry_hasBufStateInfo(ue) ) {
2592 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2594 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2595 /* If formal func param */
2596 uentry_setNullTerminatedState(ue);
2597 uentry_setLen (ue, 1);
2598 uentry_setSize (ue, 1);
2600 sRef_setNullTerminatedState(uentry_getSref(ue));
2601 sRef_setLen (uentry_getSref(ue), 1);
2602 sRef_setSize (uentry_getSref(ue), 1);
2604 uentry_setPossiblyNullTerminatedState(ue);
2606 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2610 /* put other BufState Qualifiers here */
2612 cstring s = uentry_getName(ue);
2613 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2614 struct for identifier %s\n", s) );
2616 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2618 sRef retSref = uentry_getSref (ue);
2619 ctype retType = sRef_getType (retSref);
2621 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2622 sRef_setNullTerminatedState (retSref);
2628 message ("Qualifier %s used on non-pointer on \
2629 function return: %q", qual_unparse (qel),
2630 uentry_unparse (ue)));
2637 message ("Qualifier %s used on non-pointer: %q",
2638 qual_unparse (qel), uentry_unparse (ue)));
2640 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2642 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2644 ctype realType = ctype_realType (ue->utype);
2645 sstate defstate = sstate_fromQual (qel);
2647 if (ctype_isFunction (realType))
2649 realType = ctype_realType (ctype_getReturnType (realType));
2652 if (qual_isRelDef (qel))
2654 ; /* okay anywhere */
2658 if (!ctype_isAP (realType)
2659 && !ctype_isSU (realType)
2660 && !ctype_isUnknown (realType)
2661 && !ctype_isAbstract (ue->utype))
2664 (FLG_ANNOTATIONERROR,
2665 message ("Qualifier %s used on non-pointer or struct: %q",
2666 qual_unparse (qel), uentry_unparse (ue)),
2667 uentry_whereLast (ue));
2671 uentry_setDefState (ue, defstate);
2673 if (sRef_isStateSpecial (ue->sref)
2674 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2676 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2679 else if (qual_isYield (qel))
2681 if (uentry_isVariable (ue))
2683 ue->info->var->kind = VKYIELDPARAM;
2688 (FLG_ANNOTATIONERROR,
2689 message ("Qualifier %s used on non-iterator parameter: %q",
2690 qual_unparse (qel), uentry_unparse (ue)),
2691 uentry_whereLast (ue));
2694 else if (qual_isExQual (qel))
2696 exkind ek = exkind_fromQual (qel);
2697 ctype ut = uentry_getType (ue);
2699 DPRINTF (("Reflect ex qual: %s / %s",
2700 uentry_unparse (ue), exkind_unparse (ek)));
2702 if (ctype_isFunction (ut))
2704 ut = ctype_getReturnType (ut);
2707 if (!(ctype_isVisiblySharable (ut))
2708 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2709 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2711 if (!qual_isImplied (qel))
2713 if (ctype_isImmutableAbstract (ut)) {
2715 (FLG_REDUNDANTSHAREQUAL,
2716 message ("Qualifier %s used on unsharable storage type %t: %q",
2717 exkind_unparse (ek), ut, uentry_getName (ue)),
2718 uentry_whereLast (ue));
2721 (FLG_MISPLACEDSHAREQUAL,
2722 message ("Qualifier %s used on unsharable storage type %t: %q",
2723 exkind_unparse (ek), ut, uentry_getName (ue)),
2724 uentry_whereLast (ue));
2730 alkind ak = sRef_getAliasKind (ue->sref);
2732 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2733 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2735 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2737 if (!alkind_isTemp (ak))
2739 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2740 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2743 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2744 || alkind_isOwned (ak))
2752 message ("Exposure qualifier %s used on %s storage (should "
2753 "be dependent): %q",
2755 alkind_unparse (ak),
2756 uentry_unparse (ue)));
2760 else if (qual_isGlobCheck (qel))
2762 if (uentry_isVariable (ue))
2764 chkind ch = chkind_fromQual (qel);
2766 if (ue->info->var->checked != CH_UNKNOWN)
2768 if (ch == ue->info->var->checked)
2770 llerror (FLG_SYNTAX,
2771 message ("Redundant %s qualifier on %q",
2773 uentry_getName (ue)));
2777 llerror (FLG_SYNTAX,
2779 ("Contradictory %s and %s qualifiers on %q",
2781 checkedName (ue->info->var->checked),
2782 uentry_getName (ue)));
2786 ue->info->var->checked = ch;
2792 message ("Qualifier %s used with non-variable",
2793 qual_unparse (qel)));
2796 else if (qual_isReturned (qel))
2798 if (uentry_isVariable (ue))
2800 ue->info->var->kind = VKRETPARAM;
2804 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2805 qual_unparse (qel)));
2810 uentry_reflectOtherQualifier (ue, qel);
2813 sRef_storeState (ue->sref);
2814 } end_qualList_elements;
2818 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2822 uentry_isOnly (uentry ue)
2824 return (!uentry_isUndefined (ue)
2825 && uentry_isVariable (ue)
2826 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2830 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2832 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2833 sRef_setOrigAliasKind (ue->sref, ak);
2837 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2839 if (uentry_isVariable (ue))
2841 ue->info->var->nullstate = ns;
2844 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2848 uentry_isUnique (uentry ue)
2850 return (!uentry_isUndefined (ue)
2851 && uentry_isVariable (ue)
2852 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2856 uentry_isFileStatic (uentry ue)
2858 return (uentry_isStatic (ue)
2859 && (!uentry_isVariable (ue)
2860 || sRef_isFileStatic (uentry_getSref (ue))));
2864 uentry_isExported (uentry ue)
2866 if (uentry_isValid (ue))
2868 if (uentry_isVariable (ue))
2870 return (sRef_isRealGlobal (uentry_getSref (ue)));
2874 return !uentry_isStatic (ue);
2882 uentry_isNonLocal (uentry ue)
2884 return (uentry_isValid (ue) && uentry_isVariable (ue)
2885 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2889 uentry_isGlobalVariable (uentry ue)
2891 return (uentry_isValid (ue) && uentry_isVariable (ue)
2892 && sRef_isFileOrGlobalScope (ue->sref));
2896 uentry_isVisibleExternally (uentry ue)
2898 return (uentry_isValid (ue)
2899 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2900 || (!uentry_isStatic (ue)
2901 && (uentry_isFunction (ue)
2902 || uentry_isIter (ue)
2903 || uentry_isEndIter (ue)
2904 || uentry_isConstant (ue)
2905 || uentry_isDatatype (ue)
2906 || uentry_isAnyTag (ue)))));
2910 uentry_isPrintfLike (uentry ue)
2912 return (uentry_isFunction (ue)
2913 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2917 uentry_isScanfLike (uentry ue)
2919 return (uentry_isFunction (ue)
2920 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2924 uentry_isMessageLike (uentry ue)
2926 return (uentry_isFunction (ue)
2927 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2930 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2932 uentryList args = uentry_getParams (ue);
2934 if (!uentryList_isMissingParams (args))
2936 uentry last = uentry_undefined;
2938 uentryList_elements (args, current)
2940 if (uentry_isElipsisMarker (current))
2942 if (uentry_isUndefined (last))
2946 message ("Function %q is marked %s, but has no format "
2947 "string argument before elipsis",
2948 uentry_getName (ue),
2949 specCode_unparse (ue->info->fcn->specialCode)),
2950 uentry_whereLast (ue));
2951 ue->info->fcn->specialCode = SPC_NONE;
2955 ctype rt = ctype_realType (uentry_getType (last));
2957 if (!ctype_match (rt, ctype_string))
2961 /* wchar_t * is okay too */
2962 if (ctype_isAP (rt))
2964 ctype base = ctype_baseArrayPtr (rt);
2966 if (ctype_isArbitraryIntegral (base))
2976 message ("Function %q is marked %s, but the argument "
2977 "before the elipsis has type %s (should be char *)",
2978 uentry_getName (ue),
2979 specCode_unparse (ue->info->fcn->specialCode),
2980 ctype_unparse (uentry_getType (last))),
2981 uentry_whereLast (ue));
2983 ue->info->fcn->specialCode = SPC_NONE;
2990 } end_uentryList_elements ;
2994 message ("Function %q is marked %s, but has no elipsis parameter",
2995 uentry_getName (ue),
2996 specCode_unparse (ue->info->fcn->specialCode)),
2997 uentry_whereLast (ue));
2999 ue->info->fcn->specialCode = SPC_NONE;
3004 uentry_setPrintfLike (uentry ue)
3006 uentry_convertVarFunction (ue);
3007 llassertfatal (uentry_isFunction (ue));
3008 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3009 checkSpecialFunction (ue);
3013 uentry_setScanfLike (uentry ue)
3015 uentry_convertVarFunction (ue);
3016 llassertfatal (uentry_isFunction (ue));
3017 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3018 checkSpecialFunction (ue);
3022 uentry_setMessageLike (uentry ue)
3024 uentry_convertVarFunction (ue);
3025 llassertfatal (uentry_isFunction (ue));
3026 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3027 checkSpecialFunction (ue);
3031 uentry_isSpecialFunction (uentry ue)
3033 return (uentry_isFunction (ue)
3034 && (ue->info->fcn->specialCode != SPC_NONE));
3037 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3039 ctype ct = idDecl_getCtype (t);
3041 fileloc loc = setLocation ();
3042 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3043 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3045 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3046 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3047 uentry_implicitParamAnnots (ue);
3049 /* Parameter type [][] or [x][] is invalid */
3051 while (ctype_isFixedArray (base)) {
3052 base = ctype_baseArrayPtr (base);
3055 if (ctype_isIncompleteArray (base)) {
3056 base = ctype_baseArrayPtr (base);
3058 if (ctype_isArray (base)) {
3059 if (!uentry_hasName (ue)) {
3060 (void) optgenerror (FLG_INCOMPLETETYPE,
3061 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3063 ctype_unparse (ct)),
3064 uentry_whereLast (ue));
3066 (void) optgenerror (FLG_INCOMPLETETYPE,
3067 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3068 uentry_getName (ue),
3069 ctype_unparse (ct)),
3070 uentry_whereLast (ue));
3075 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3079 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3081 ctype ct = idDecl_getCtype (t);
3083 if (ctype_isFunction (ct))
3085 return (uentry_makeIdFunction (t));
3089 fileloc loc = setLocation ();
3090 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3092 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3094 if (!uentry_isExtern (ue))
3096 uentry_setDefined (ue, loc);
3104 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3106 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3114 static /*@only@*/ /*@notnull@*/
3115 uentry uentry_makeConstantAux (cstring n, ctype t,
3116 /*@keep@*/ fileloc f, bool priv, bool macro,
3117 /*@only@*/ multiVal m)
3119 uentry e = uentry_alloc ();
3122 e->uname = cstring_copy (n);
3124 e->storageclass = SCNONE;
3126 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3128 e->sref = sRef_makeConst (t);
3133 e->uses = filelocList_new ();
3134 e->isPrivate = priv;
3135 e->hasNameError = FALSE;
3137 e->info = (uinfo) dmalloc (sizeof (*e->info));
3138 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3139 e->info->uconst->access = typeIdSet_undefined;
3140 e->info->uconst->macro = macro;
3142 uentry_setSpecDef (e, f);
3144 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3146 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3149 uentry_setConstantValue (e, m);
3154 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3156 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3160 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3162 uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3166 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3168 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3172 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3174 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3175 idDecl_getCtype (t),
3178 llassert (fileloc_isUndefined (ue->whereDeclared));
3179 ue->whereDeclared = setLocation ();
3180 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3182 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3183 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3191 void uentry_setDefState (uentry ue, sstate defstate)
3193 if (uentry_isValid (ue))
3195 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3197 if (uentry_isVariable (ue))
3199 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3204 bool uentry_isCheckedUnknown (uentry ue)
3206 return (uentry_isVar (ue)
3207 && (ue->info->var->checked == CH_UNKNOWN));
3210 bool uentry_isCheckMod (uentry ue)
3212 return (uentry_isVar (ue)
3213 && (ue->info->var->checked == CH_CHECKMOD));
3216 bool uentry_isUnchecked (uentry ue)
3218 return (uentry_isVar (ue)
3219 && (ue->info->var->checked == CH_UNCHECKED));
3222 bool uentry_isChecked (uentry ue)
3224 return (uentry_isVar (ue)
3225 && (ue->info->var->checked == CH_CHECKED));
3228 bool uentry_isCheckedModify (uentry ue)
3230 return (uentry_isVar (ue)
3231 && (ue->info->var->checked == CH_CHECKED
3232 || ue->info->var->checked == CH_CHECKMOD
3233 || ue->info->var->checked == CH_CHECKEDSTRICT));
3236 bool uentry_isCheckedStrict (uentry ue)
3238 return (uentry_isVar (ue)
3239 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3242 void uentry_setUnchecked (uentry ue)
3244 llassert (uentry_isVar (ue));
3246 ue->info->var->checked = CH_UNCHECKED;
3249 void uentry_setChecked (uentry ue)
3251 llassert (uentry_isVar (ue));
3253 ue->info->var->checked = CH_CHECKED;
3256 void uentry_setCheckMod (uentry ue)
3258 llassert (uentry_isVar (ue));
3260 ue->info->var->checked = CH_CHECKMOD;
3263 void uentry_setCheckedStrict (uentry ue)
3265 llassert (uentry_isVar (ue));
3267 ue->info->var->checked = CH_CHECKEDSTRICT;
3270 static /*@only@*/ /*@notnull@*/
3271 uentry uentry_makeVariableAux (cstring n, ctype t,
3273 /*@exposed@*/ sRef s,
3274 bool priv, vkind kind)
3276 uentry e = uentry_alloc ();
3279 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3282 e->uname = cstring_copy (n);
3285 e->storageclass = SCNONE;
3287 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3294 e->uses = filelocList_new ();
3295 e->isPrivate = priv;
3296 e->hasNameError = FALSE;
3298 e->info = (uinfo) dmalloc (sizeof (*e->info));
3299 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3300 e->info->var->kind = kind;
3302 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3303 e->info->var->checked = CH_UNKNOWN;
3305 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3306 uentry_setSpecDef (e, f);
3307 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3309 if (ctype_isFunction (rt))
3311 rt = ctype_getReturnType (rt);
3314 if (ctype_isUA (rt))
3316 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3317 sRef_setStateFromType (e->sref, rt);
3320 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3321 e->info->var->defstate = sRef_getDefState (e->sref);
3322 e->info->var->nullstate = sRef_getNullState (e->sref);
3324 /* start modifications */
3325 /* This function sets the uentry for a pointer or array variable declaration,
3326 it allocates memory and sets the fields. We check if the type of the variable
3327 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3329 if (ctype_isArray (t) || ctype_isPointer(t))
3331 /*@i222@*/ e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3332 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3333 sRef_setNotNullTerminatedState (s);
3337 e->info->var->bufinfo = NULL;
3339 /* end modification */
3345 uentry_isYield (uentry ue)
3347 return (uentry_isVariable (ue)
3348 && (ue->info->var->kind == VKYIELDPARAM
3349 || ue->info->var->kind == VKREFYIELDPARAM));
3353 uentry_isRefsField (uentry ue)
3355 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3358 /*@only@*/ /*@notnull@*/
3359 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3361 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3362 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3369 void uentry_makeVarFunction (uentry ue)
3376 llassert (uentry_isValid (ue));
3377 llassert (!sRef_modInFunction ());
3379 ak = sRef_getOrigAliasKind (ue->sref);
3380 ek = sRef_getOrigExKind (ue->sref);
3382 llassert (uentry_isVariable (ue));
3383 oldInfo = ue->info->var;
3385 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3386 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3389 ** expanded macro is marked used
3392 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3395 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3396 ue->info->fcn->exitCode = XK_UNKNOWN;
3397 ue->info->fcn->nullPred = qual_createUnknown ();
3398 ue->info->fcn->specialCode = SPC_NONE;
3399 ue->info->fcn->access = typeIdSet_undefined;
3400 ue->info->fcn->hasGlobs = FALSE;
3401 ue->info->fcn->globs = globSet_undefined;
3402 ue->info->fcn->hasMods = FALSE;
3403 ue->info->fcn->mods = sRefSet_undefined;
3404 ue->info->fcn->specclauses = NULL;
3405 ue->info->fcn->defparams = uentryList_undefined;
3408 ue->info->fcn->preconditions = functionConstraint_undefined;
3412 ue->info->fcn->postconditions = functionConstraint_undefined;
3415 if (ctype_isFunction (ue->utype))
3417 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3421 ue->sref = sRef_makeType (ctype_unknown);
3424 if (sRef_isRefCounted (ue->sref))
3430 if (alkind_isUnknown (ak))
3432 if (exkind_isKnown (ek))
3434 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3435 ak = AK_IMPDEPENDENT;
3439 if (context_getFlag (FLG_RETIMPONLY))
3441 if (ctype_isFunction (ue->utype)
3442 && ctype_isVisiblySharable
3443 (ctype_realType (ctype_getReturnType (ue->utype))))
3445 if (uentryList_hasReturned (uentry_getParams (ue)))
3451 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3466 loc = ue->whereDeclared;
3468 sRef_setAliasKind (ue->sref, ak, loc);
3469 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3470 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3471 sRef_setExKind (ue->sref, ek, loc);
3473 if (oldInfo->kind == VKEXPMACRO)
3479 fileloc_free (ue->whereDefined);
3480 ue->whereDefined = fileloc_undefined;
3483 uvinfo_free (oldInfo);
3486 void uentry_makeConstantFunction (uentry ue)
3493 llassert (uentry_isValid (ue));
3494 llassert (!sRef_modInFunction ());
3496 ak = sRef_getOrigAliasKind (ue->sref);
3497 ek = sRef_getOrigExKind (ue->sref);
3499 llassert (uentry_isConstant (ue));
3500 oldInfo = ue->info->uconst;
3502 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3505 ** expanded macro is marked used (until I write a pre-processor)
3509 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3510 ue->info->fcn->exitCode = XK_UNKNOWN;
3511 ue->info->fcn->nullPred = qual_createUnknown ();
3512 ue->info->fcn->specialCode = SPC_NONE;
3513 ue->info->fcn->access = typeIdSet_undefined;
3514 ue->info->fcn->hasGlobs = FALSE;
3515 ue->info->fcn->globs = globSet_undefined;
3516 ue->info->fcn->hasMods = FALSE;
3517 ue->info->fcn->mods = sRefSet_undefined;
3518 ue->info->fcn->specclauses = NULL;
3519 ue->info->fcn->defparams = uentryList_undefined;
3522 ue->info->fcn->preconditions = functionConstraint_undefined;
3526 ue->info->fcn->postconditions = functionConstraint_undefined;
3530 if (ctype_isFunction (ue->utype))
3532 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3536 ue->sref = sRef_makeType (ctype_unknown);
3539 if (sRef_isRefCounted (ue->sref))
3545 if (alkind_isUnknown (ak))
3547 if (exkind_isKnown (ek))
3549 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3550 ak = AK_IMPDEPENDENT;
3554 if (context_getFlag (FLG_RETIMPONLY))
3556 if (ctype_isFunction (ue->utype)
3557 && ctype_isVisiblySharable
3558 (ctype_realType (ctype_getReturnType (ue->utype))))
3560 if (uentryList_hasReturned (uentry_getParams (ue)))
3566 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3581 loc = ue->whereDeclared;
3583 sRef_setAliasKind (ue->sref, ak, loc);
3584 sRef_setExKind (ue->sref, ek, loc);
3586 fileloc_free (ue->whereDefined);
3587 ue->whereDefined = fileloc_undefined;
3588 ucinfo_free (oldInfo);
3592 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3594 llassert (uentry_isValid (ue));
3596 if (uentry_isIter (ue))
3598 llassert (globSet_isUndefined (ue->info->iter->globs));
3599 ue->info->iter->globs = globs;
3603 uentry_convertVarFunction (ue);
3605 llassert (uentry_isFunction (ue));
3606 llassert (!ue->info->fcn->hasGlobs
3607 && globSet_isUndefined (ue->info->fcn->globs));
3609 ue->info->fcn->hasGlobs = TRUE;
3610 globSet_markImmutable (globs);
3611 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3616 /* ??? - evans 2001-09-09 not sure what's going on here...?
3617 if (globSet_hasStatic (globs))
3619 context_recordFileGlobals (globs);
3623 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3625 ue->info->fcn->hasMods = TRUE;
3629 void uentry_addAccessType (uentry ue, typeId tid)
3631 if (uentry_isFunction (ue))
3633 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3635 else if (uentry_isEitherConstant (ue))
3637 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3639 else if (uentry_isIter (ue))
3641 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3643 else if (uentry_isEndIter (ue))
3645 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3649 llbug (message ("no access for: %q", uentry_unparse (ue)));
3653 /*@only@*/ /*@notnull@*/ uentry
3654 uentry_makeFunction (cstring n, ctype t,
3656 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3657 /*@only@*/ warnClause warn,
3660 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3661 return (uentry_makeFunctionAux (n, t,
3662 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3663 : typeIdSet_single (access)),
3670 /*@notnull@*/ uentry
3671 uentry_makePrivFunction2 (cstring n, ctype t,
3673 globSet globs, sRefSet mods,
3676 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3681 /*@notnull@*/ uentry
3682 uentry_makeSpecFunction (cstring n, ctype t,
3684 /*@only@*/ globSet globs,
3685 /*@only@*/ sRefSet mods,
3688 uentry ue = uentry_makeFunctionAux (n, t, access,
3689 globs, mods, warnClause_undefined,
3692 uentry_setHasGlobs (ue);
3693 uentry_setHasMods (ue);
3695 reflectImplicitFunctionQualifiers (ue, TRUE);
3700 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3702 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3703 sRef_undefined, FALSE, VKEXPMACRO);
3705 uentry_setDefined (ue, f);
3709 /*@notnull@*/ /*@notnull@*/ uentry
3710 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3712 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3713 typeIdSet_singleOpt (access),
3714 globSet_undefined, sRefSet_undefined,
3715 warnClause_undefined,
3719 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3723 bool uentry_isForward (uentry e)
3725 if (uentry_isValid (e))
3727 ctype ct = uentry_getType (e);
3729 return (ctype_isUnknown (ct)
3730 || (ctype_isFunction (ct)
3731 && ctype_isUnknown (ctype_getReturnType (ct))));
3738 /*@notnull@*/ uentry
3739 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3741 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3742 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3746 /*@notnull@*/ uentry
3747 uentry_makeUnspecFunction (cstring n, ctype t,
3751 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3752 sRefSet_undefined, warnClause_undefined,
3755 reflectImplicitFunctionQualifiers (ue, TRUE);
3764 /* is exported for use by usymtab_interface */
3766 /*@notnull@*/ uentry
3767 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3768 fileloc f, bool priv)
3770 uentry e = uentry_alloc ();
3772 DPRINTF (("Make datatype: %s / %s",
3773 n, ctype_unparse (t)));
3775 /* e->shallowCopy = FALSE; */
3776 e->ukind = KDATATYPE;
3777 e->uname = cstring_copy (n);
3779 e->storageclass = SCNONE;
3780 e->sref = sRef_makeUnknown ();
3784 sRef_setStateFromType (e->sref, t);
3787 uentry_setSpecDef (e, f);
3789 e->warn = warnClause_undefined; /*@i634@*/
3790 e->uses = filelocList_new ();
3791 e->isPrivate = priv;
3792 e->hasNameError = FALSE;
3797 e->info = (uinfo) dmalloc (sizeof (*e->info));
3798 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3799 e->info->datatype->abs = abstract;
3800 e->info->datatype->mut = mut;
3801 e->info->datatype->type = ctype_undefined;
3803 if (uentry_isDeclared (e))
3805 uentry_setDefined (e, f);
3808 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3810 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3816 /*@notnull@*/ uentry
3817 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3819 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3822 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3824 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3825 ctype_bool, NO, abstract,
3826 fileloc_getBuiltin (),
3829 ret->info->datatype->type = ctype_bool;
3837 static /*@only@*/ /*@notnull@*/ uentry
3838 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3839 /*@only@*/ fileloc f)
3841 uentry e = uentry_alloc ();
3844 e->uname = cstring_copy (n);
3846 e->sref = sRef_makeUnknown ();
3847 e->storageclass = SCNONE;
3851 uentry_setSpecDef (e, f);
3853 e->warn = warnClause_undefined; /*@i452@*/
3854 e->uses = filelocList_new ();
3855 e->isPrivate = FALSE;
3856 e->hasNameError = FALSE;
3858 e->info = (uinfo) dmalloc (sizeof (*e->info));
3859 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3860 e->info->iter->access = access;
3861 e->info->iter->mods = sRefSet_undefined;
3862 e->info->iter->globs = globSet_undefined;
3864 uentry_checkIterArgs (e);
3868 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3870 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3873 static /*@notnull@*/ uentry
3874 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3876 uentry e = uentry_alloc ();
3878 /* e->shallowCopy = FALSE; */
3879 e->ukind = KENDITER;
3880 e->storageclass = SCNONE;
3881 e->uname = message ("end_%s", n);
3882 e->utype = ctype_unknown;
3883 e->sref = sRef_makeUnknown ();
3885 uentry_setSpecDef (e, f);
3890 e->uses = filelocList_new ();
3891 e->isPrivate = FALSE;
3892 e->hasNameError = FALSE;
3894 e->info = (uinfo) dmalloc (sizeof (*e->info));
3895 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3897 e->info->enditer->access = access;
3899 e->warn = warnClause_undefined; /*@i452@*/
3903 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3905 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3912 static /*@only@*/ /*@notnull@*/ uentry
3913 uentry_makeTagAux (cstring n, ctype t,
3914 /*@only@*/ fileloc fl,
3915 bool priv, ekind kind)
3917 uentry e = uentry_alloc ();
3919 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3921 llbuglit ("uentry_makeTagAux: not a tag type");
3925 /* e->shallowCopy = FALSE; */
3926 e->uname = cstring_copy (n);
3929 e->sref = sRef_makeUnknown ();
3930 e->storageclass = SCNONE;
3932 uentry_setSpecDef (e, fl);
3937 e->uses = filelocList_new ();
3938 e->isPrivate = priv;
3939 e->hasNameError = FALSE;
3941 e->info = (uinfo) dmalloc (sizeof (*e->info));
3942 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3943 e->info->datatype->abs = NO;
3944 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3945 e->info->datatype->type = t;
3946 e->warn = warnClause_undefined; /*@i452@*/
3948 if (uentry_isDeclared (e))
3950 uentry_setDefined (e, fl);
3956 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3958 cstring sname = makeStruct (n);
3959 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3961 cstring_free (sname);
3966 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3968 cstring sname = makeStruct (n);
3969 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3971 cstring_free (sname);
3976 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3978 cstring uname = makeUnion (n);
3979 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3981 cstring_free (uname);
3987 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3989 cstring ename = makeEnum (n);
3990 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3992 cstring_free (ename);
3998 uentry_makeUnionTagLoc (cstring n, ctype t)
4000 cstring uname = makeUnion (n);
4001 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4003 cstring_free (uname);
4008 uentry_makeEnumTagLoc (cstring n, ctype t)
4010 cstring ename = makeEnum (n);
4011 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4013 cstring_free (ename);
4018 uentry_isStructTag (uentry ue)
4020 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4024 uentry_isUnionTag (uentry ue)
4026 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4030 uentry_isEnumTag (uentry ue)
4032 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4036 uentry_isAnyTag (uentry ue)
4038 return (uentry_isStructTag (ue)
4039 || uentry_isUnionTag (ue)
4040 || uentry_isEnumTag (ue));
4043 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4045 extern void uentry_destroyMod (void)
4046 /*@globals killed emarker@*/ /*@modifies emarker@*/
4048 static bool wasDestroyed = FALSE;
4050 llassert (!wasDestroyed);
4052 if (emarker != NULL)
4054 uentry_reallyFree (emarker);
4057 wasDestroyed = TRUE;
4061 uentry_makeElipsisMarker (void)
4063 if (emarker == NULL)
4065 emarker = uentry_alloc ();
4067 emarker->ukind = KELIPSMARKER;
4068 emarker->uname = cstring_makeLiteral ("...");
4069 emarker->utype = ctype_elipsMarker;
4070 emarker->sref = sRef_undefined;
4071 emarker->storageclass = SCNONE;
4072 emarker->used = FALSE;
4073 emarker->lset = FALSE;
4074 emarker->info = NULL;
4076 uentry_setSpecDef (emarker, fileloc_undefined);
4077 emarker->uses = filelocList_new ();
4078 emarker->isPrivate = FALSE;
4079 emarker->hasNameError = FALSE;
4082 /*@ignore@*/ return (emarker); /*@end@*/
4090 uentry_equiv (uentry p1, uentry p2)
4092 if (uentry_compare (p1, p2) != 0)
4103 uentry_xcomparealpha (uentry *p1, uentry *p2)
4107 if ((res = uentry_compare (*p1, *p2)) == 0) {
4108 if ((*p1 != NULL) && (*p2 != NULL)) {
4109 res = cstring_compare ((*p1)->uname,
4118 uentry_xcompareuses (uentry *p1, uentry *p2)
4123 if (uentry_isValid (u1))
4125 if (uentry_isValid (u2))
4127 return (-1 * int_compare (filelocList_size (u1->uses),
4128 filelocList_size (u2->uses)));
4137 if (uentry_isValid (u2))
4149 uentry_compareStrict (uentry v1, uentry v2)
4151 COMPARERETURN (uentry_compare (v1, v2));
4153 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4155 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4156 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4157 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4164 uentry_compare (uentry u1, uentry u2)
4166 if (u1 == u2) return 0;
4168 if (uentry_isInvalid (u1)) return -1;
4169 if (uentry_isInvalid (u2)) return 1;
4171 INTCOMPARERETURN (u1->ukind, u2->ukind);
4172 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4173 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4174 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4180 /* bug detected by splint:
4181 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4186 return (multiVal_compare (uentry_getConstantValue (u1),
4187 uentry_getConstantValue (u2)));
4191 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4193 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4194 uentry_accessType (u2)));
4195 return (uentryList_compareParams (uentry_getParams (u1),
4196 uentry_getParams (u2)));
4198 return (typeIdSet_compare (uentry_accessType (u1),
4199 uentry_accessType (u2)));
4202 ** Functions are never equivalent
4205 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4215 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4216 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4217 sRef_getOrigAliasKind (u2->sref)));
4218 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4219 sRef_getOrigExKind (u2->sref)));
4220 COMPARERETURN (generic_compare (u1->info->var->checked,
4221 u2->info->var->checked));
4222 COMPARERETURN (generic_compare (u1->info->var->defstate,
4223 u2->info->var->defstate));
4224 return (generic_compare (u1->info->var->nullstate,
4225 u2->info->var->nullstate));
4227 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4228 u2->info->datatype->type));
4229 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4230 u2->info->datatype->mut));
4231 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4240 ** all entries are: <type>[@<info>]*#<name>
4242 ** info depends on kind:
4246 advanceField (char **s)
4248 reader_checkChar (s, '@');
4252 advanceName (char **s)
4254 reader_checkChar (s, '#');
4258 vkind_fromInt (int i)
4260 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4262 llbuglit ("vkind_fromInt: out of range");
4269 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4270 typeIdSet access, nstate nullstate,
4271 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4273 uentry e = uentry_alloc ();
4278 e->sref = sRef_makeConst (ct);
4280 sRef_setNullState (e->sref, nullstate, loc);
4281 e->storageclass = SCNONE;
4283 if (fileloc_isSpec (loc))
4285 e->whereSpecified = loc;
4286 e->whereDeclared = fileloc_undefined;
4290 e->whereSpecified = fileloc_undefined;
4291 e->whereDeclared = loc;
4294 e->whereDefined = fileloc_undefined;
4295 e->uses = filelocList_new ();
4296 e->isPrivate = FALSE;
4297 e->hasNameError = FALSE;
4302 e->warn = warnClause_undefined; /*@i452@*/
4304 e->info = (uinfo) dmalloc (sizeof (*e->info));
4305 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4306 e->info->uconst->access = access;
4307 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
4308 uentry_setConstantValue (e, m);
4309 sRef_storeState (e->sref);
4314 static /*@only@*/ uentry
4315 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4316 sstate defstate, nstate isnull, alkind aliased,
4317 exkind exp, chkind checked,
4318 /*@only@*/ fileloc loc)
4320 uentry e = uentry_alloc ();
4325 e->storageclass = SCNONE;
4327 e->sref = sRef_makeType (ct);
4328 sRef_setNullState (e->sref, isnull, loc);
4330 e->whereDefined = fileloc_undefined;
4332 if (fileloc_isSpec (loc))
4334 e->whereSpecified = loc;
4335 e->whereDeclared = fileloc_undefined;
4339 e->whereSpecified = fileloc_undefined;
4340 e->whereDeclared = loc;
4343 e->isPrivate = FALSE;
4344 e->hasNameError = FALSE;
4349 e->uses = filelocList_new ();
4350 e->warn = warnClause_undefined; /*@i452@*/
4352 e->info = (uinfo) dmalloc (sizeof (*e->info));
4353 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4354 e->info->var->kind = kind;
4355 e->info->var->checked = checked;
4356 e->info->var->defstate = defstate;
4358 sRef_setDefState (e->sref, defstate, loc);
4360 e->info->var->nullstate = sRef_getNullState (e->sref);
4362 sRef_setExKind (e->sref, exp, loc);
4363 sRef_setAliasKind (e->sref, aliased, loc);
4365 sRef_storeState (e->sref);
4367 /*DRL ADDED 9-1-2000 */
4368 e->info->var->bufinfo = NULL;
4373 static /*@only@*/ uentry
4374 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4375 ynm mut, ctype rtype, alkind ak, exkind exp,
4376 sstate defstate, nstate isnull,
4377 /*@only@*/ fileloc loc)
4379 uentry e = uentry_alloc ();
4381 e->ukind = KDATATYPE;
4382 /* e->shallowCopy = FALSE; */
4385 e->storageclass = SCNONE;
4386 e->sref = sRef_makeUnknown ();
4387 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4390 ** This is only setting null state. (I think?)
4393 if (ctype_isUA (ct))
4395 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4397 if (uentry_isValid (te))
4399 sRef_setStateFromUentry (e->sref, te);
4403 /* problem for recursive type definitions */
4407 sRef_setAliasKind (e->sref, ak, loc);
4408 sRef_setExKind (e->sref, exp, loc);
4410 sRef_setDefState (e->sref, defstate, loc);
4412 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4414 isnull = NS_ABSNULL;
4417 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4418 sRef_mergeNullState (e->sref, isnull);
4420 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4422 if (fileloc_isSpec (loc))
4424 e->whereSpecified = loc;
4425 e->whereDeclared = fileloc_undefined;
4429 e->whereSpecified = fileloc_undefined;
4430 e->whereDeclared = loc;
4433 e->isPrivate = FALSE;
4434 e->hasNameError = FALSE;
4436 e->warn = warnClause_undefined; /*@i452@*/
4440 e->uses = filelocList_new ();
4442 e->info = (uinfo) dmalloc (sizeof (*e->info));
4443 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4444 e->info->datatype->abs = abstract;
4445 e->info->datatype->mut = mut;
4446 e->info->datatype->type = rtype;
4448 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4449 sRef_storeState (e->sref);
4450 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4456 static void uentry_setHasGlobs (uentry ue)
4458 llassert (uentry_isFunction (ue));
4460 ue->info->fcn->hasGlobs = TRUE;
4463 static void uentry_setHasMods (uentry ue)
4465 llassert (uentry_isFunction (ue));
4467 ue->info->fcn->hasMods = TRUE;
4471 bool uentry_hasGlobs (uentry ue)
4473 if (uentry_isFunction (ue))
4475 return (ue->info->fcn->hasGlobs);
4481 bool uentry_hasStateClauseList (uentry ue)
4483 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4486 bool uentry_hasConditions (uentry ue)
4488 return (uentry_isFunction (ue)
4489 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4490 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4493 stateClauseList uentry_getStateClauseList (uentry ue)
4495 if (!uentry_isFunction (ue))
4497 llassert (uentry_isFunction (ue));
4498 return stateClauseList_undefined;
4501 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4502 return ue->info->fcn->specclauses;
4505 bool uentry_hasMods (uentry ue)
4507 if (uentry_isFunction (ue))
4509 return (ue->info->fcn->hasMods);
4516 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4518 bool hasGlobs, /*@only@*/ globSet globs,
4519 bool hasMods, /*@only@*/ sRefSet mods,
4520 alkind ak, exkind exp,
4521 sstate defstate, nstate isnull,
4525 /*@only@*/ stateClauseList specclauses,
4526 /*@only@*/ warnClause warnclause,
4527 /*@only@*/ fileloc loc)
4529 uentry e = uentry_alloc ();
4532 /* e->shallowCopy = FALSE; */
4536 e->storageclass = SCNONE;
4538 if (ctype_isFunction (ct))
4540 ret = ctype_getReturnType (ct);
4544 if (ctype_isKnown (ct))
4546 llbug (message ("not function: %s", ctype_unparse (ct)));
4549 ret = ctype_unknown;
4552 e->sref = sRef_makeType (ret);
4554 if (ctype_isUA (ret))
4556 sRef_setStateFromType (e->sref, ret);
4559 sRef_setDefined (e->sref, loc);
4560 sRef_setNullState (e->sref, isnull, loc);
4562 sRef_setAliasKind (e->sref, ak, loc);
4563 sRef_setExKind (e->sref, exp, loc);
4564 sRef_setDefState (e->sref, defstate, loc);
4566 e->whereSpecified = loc;
4567 e->whereDefined = fileloc_undefined;
4569 e->isPrivate = FALSE;
4570 e->hasNameError = FALSE;
4574 e->uses = filelocList_new ();
4575 e->warn = warnclause;
4577 e->info = (uinfo) dmalloc (sizeof (*e->info));
4578 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4580 e->info->fcn->exitCode = exitCode;
4581 e->info->fcn->specialCode = sCode;
4582 e->info->fcn->nullPred = nullPred;
4583 e->info->fcn->access = access;
4585 e->info->fcn->specclauses = specclauses;
4586 e->info->fcn->hasGlobs = hasGlobs;
4587 e->info->fcn->globs = globs;
4589 e->info->fcn->hasMods = hasMods;
4590 e->info->fcn->mods = mods;
4592 e->info->fcn->defparams = uentryList_undefined;
4593 e->whereDeclared = fileloc_undefined;
4595 sRef_storeState (e->sref);
4598 e->info->fcn->preconditions = NULL;
4602 e->info->fcn->postconditions = NULL;
4608 static /*@only@*/ uentry
4609 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4610 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4612 uentry e = uentry_alloc ();
4614 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4616 llbuglit ("uentry_makeTagBase: not a tag type");
4619 /* e->shallowCopy = FALSE; */
4623 e->sref = sRef_makeUnknown ();
4624 e->storageclass = SCNONE;
4626 if (fileloc_isSpec (loc))
4628 e->whereSpecified = loc;
4629 e->whereDeclared = fileloc_undefined;
4633 e->whereDeclared = loc;
4634 e->whereSpecified = fileloc_undefined;
4637 e->whereDefined = fileloc_undefined;
4639 e->isPrivate = FALSE;
4640 e->hasNameError = FALSE;
4644 e->uses = filelocList_new ();
4645 e->warn = warnClause_undefined; /*@i452@*/
4647 e->info = (uinfo) dmalloc (sizeof (*e->info));
4648 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4649 e->info->datatype->abs = NO;
4650 e->info->datatype->mut = MAYBE;
4651 e->info->datatype->type = rtype;
4653 sRef_storeState (e->sref);
4659 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4660 ctype ct, /*@only@*/ fileloc loc)
4662 uentry e = uentry_alloc ();
4664 /* e->shallowCopy = FALSE; */
4668 e->sref = sRef_makeUnknown ();
4669 e->storageclass = SCNONE;
4671 if (fileloc_isSpec (loc))
4673 e->whereSpecified = loc;
4674 e->whereDeclared = fileloc_undefined;
4678 e->whereDeclared = loc;
4679 e->whereSpecified = fileloc_undefined;
4682 e->whereDefined = fileloc_undefined;
4684 e->isPrivate = FALSE;
4685 e->hasNameError = FALSE;
4689 e->uses = filelocList_new ();
4690 e->warn = warnClause_undefined; /*@i452@*/
4692 e->info = (uinfo) dmalloc (sizeof (*e->info));
4693 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4694 e->info->iter->access = access;
4695 e->info->iter->mods = sRefSet_undefined;
4696 e->info->iter->globs = globSet_undefined;
4698 sRef_storeState (e->sref);
4703 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4704 /*@only@*/ fileloc loc)
4706 uentry e = uentry_alloc ();
4708 /* e->shallowCopy = FALSE; */
4709 e->ukind = KENDITER;
4710 e->storageclass = SCNONE;
4712 e->utype = ctype_unknown;
4713 e->sref = sRef_makeUnknown ();
4715 if (fileloc_isSpec (loc))
4717 e->whereSpecified = loc;
4718 e->whereDeclared = fileloc_undefined;
4722 e->whereDeclared = loc;
4723 e->whereSpecified = fileloc_undefined;
4726 e->whereDefined = fileloc_undefined;
4728 e->isPrivate = FALSE;
4729 e->hasNameError = FALSE;
4733 e->uses = filelocList_new ();
4734 e->warn = warnClause_undefined; /*@i452@*/
4736 e->info = (uinfo) dmalloc (sizeof (*e->info));
4737 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4738 e->info->enditer->access = access;
4739 sRef_storeState (e->sref);
4744 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4752 uentry_undump (ekind kind, fileloc loc, char **s)
4756 DPRINTF (("Uentry undump: %s", *s));
4760 reader_checkChar (s, '!');
4761 reader_checkChar (s, '.');
4762 ue = uentry_makeElipsisMarker ();
4766 ctype ct = ctype_undump (s);
4780 reader_checkChar (s, '|');
4782 if (reader_optCheckChar (s, '@'))
4784 tkind = vkind_fromInt (reader_getInt (s));
4785 reader_checkChar (s, '|');
4792 if (reader_optCheckChar (s, '$'))
4794 defstate = SS_UNKNOWN;
4795 isnull = NS_UNKNOWN;
4796 aliased = AK_IMPTEMP;
4798 checked = CH_UNKNOWN;
4800 else if (reader_optCheckChar (s, '&'))
4802 defstate = SS_DEFINED;
4803 isnull = NS_UNKNOWN;
4804 aliased = AK_IMPTEMP;
4806 checked = CH_UNKNOWN;
4808 else if (reader_optCheckChar (s, '^'))
4810 defstate = SS_UNKNOWN;
4811 isnull = NS_UNKNOWN;
4812 aliased = AK_IMPTEMP;
4814 checked = CH_UNKNOWN;
4818 defstate = sstate_fromInt (reader_getInt (s));
4819 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4820 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4822 if (reader_optCheckChar (s, '&'))
4825 checked = CH_UNKNOWN;
4829 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4830 advanceField (s); checked = (chkind) (reader_getInt (s));
4835 name = reader_getStringWord (s);
4837 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4839 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4840 isnull, aliased, exp,
4841 checked, fileloc_copy (loc));
4854 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4855 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4856 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4857 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4858 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4859 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4860 advanceField (s); rtype = ctype_undump (s);
4862 name = reader_getStringWord (s);
4863 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4864 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4865 aliased, exp, defstate, isnull,
4866 fileloc_copy (loc));
4883 stateClauseList specclauses = stateClauseList_undefined;
4884 warnClause warnclause = warnClause_undefined;
4886 if (reader_optCheckChar (s, '$'))
4888 defstate = SS_DEFINED;
4889 isnull = NS_UNKNOWN;
4890 exitCode = XK_UNKNOWN;
4892 nullPred = qual_createUnknown ();
4896 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4897 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4898 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4899 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4900 advanceField (s); nullPred = qual_undump (s);
4903 if (reader_optCheckChar (s, '$'))
4906 globs = globSet_undefined;
4908 mods = sRefSet_undefined;
4910 else if (reader_optCheckChar (s, '^'))
4913 globs = globSet_undefined;
4915 mods = sRefSet_undefined;
4919 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4920 advanceField (s); globs = globSet_undump (s);
4921 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4922 advanceField (s); mods = sRefSet_undump (s);
4925 if (reader_optCheckChar (s, '$'))
4932 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4933 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4936 advanceField (s); access = typeIdSet_undump (s);
4939 ** Optional clauses: Start with @<code>:
4942 while (reader_optCheckChar (s, '@'))
4944 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4946 reader_checkChar (s, ':');
4947 warnclause = warnClause_undump (s);
4949 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4951 reader_checkChar (s, ':');
4952 specclauses = stateClauseList_undump (s);
4960 advanceName (s); name = reader_getStringWord (s);
4962 ue = uentry_makeFunctionBase (name, ct, access,
4965 ak, exp, defstate, isnull,
4966 exitCode, specc, nullPred,
4969 fileloc_copy (loc));
4970 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4977 advanceField (s); access = typeIdSet_undump (s);
4978 advanceName (s); name = reader_getStringWord (s);
4980 ue = uentry_makeIterBase (name, access, ct,
4981 fileloc_copy (loc));
4988 advanceField (s); access = typeIdSet_undump (s);
4989 advanceName (s); name = reader_getStringWord (s);
4991 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
5001 if (reader_optCheckChar (s, '$'))
5003 val = multiVal_undefined;
5004 access = typeIdSet_undefined;
5005 nullstate = NS_UNKNOWN;
5009 advanceField (s); val = multiVal_undump (s);
5010 advanceField (s); access = typeIdSet_undump (s);
5011 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5014 advanceName (s); name = reader_getStringWord (s);
5016 ue = uentry_makeConstantBase (name, ct, access,
5017 nullstate, fileloc_copy (loc), val);
5026 advanceField (s); rtype = ctype_undump (s);
5027 advanceName (s); name = reader_getStringWord (s);
5028 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5032 llcontbuglit ("uentry_undump: invalid");
5033 ue = uentry_undefined;
5036 llcontbuglit ("uentry_undump: elips marker");
5037 ue = uentry_undefined;
5046 uentry_dump (uentry v)
5048 return (uentry_dumpAux (v, FALSE));
5052 uentry_dumpParam (uentry v)
5054 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5055 ("dump: %s", uentry_unparseFull (v)));
5057 return (uentry_dumpAux (v, TRUE));
5061 uentry_dumpAux (uentry v, bool isParam)
5063 llassert (uentry_isValid (v));
5064 llassert (!uentry_isGlobalMarker (v));
5066 DPRINTF (("Dump uentry: [%p]", v));
5067 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5072 llcontbuglit ("uentry_dump: invalid entry");
5073 return cstring_undefined;
5075 return (message ("!."));
5079 vkind vk = v->info->var->kind;
5080 sstate dss = sRef_getDefState (v->sref);
5081 nstate nst = sRef_getNullState (v->sref);
5082 alkind alk = sRef_getAliasKind (v->sref);
5083 exkind exk = sRef_getExKind (v->sref);
5084 chkind chk = v->info->var->checked;
5086 DPRINTF (("Dumping var"));
5088 if (dss == SS_UNKNOWN
5089 && nst == NS_UNKNOWN
5090 && alk == AK_IMPTEMP
5091 && exk == XO_UNKNOWN
5092 && chk == CH_UNKNOWN)
5094 sdump = cstring_makeLiteral ("$");
5096 else if (dss == SS_DEFINED
5097 && nst == NS_UNKNOWN
5098 && alk == AK_IMPTEMP
5099 && exk == XO_UNKNOWN
5100 && chk == CH_UNKNOWN)
5102 sdump = cstring_makeLiteral ("&");
5104 else if (dss == SS_UNKNOWN
5105 && nst == NS_UNKNOWN
5106 && alk == AK_UNKNOWN
5107 && exk == XO_UNKNOWN
5108 && chk == CH_UNKNOWN)
5110 sdump = cstring_makeLiteral ("^");
5112 else if (exk == XO_UNKNOWN
5113 && chk == CH_UNKNOWN)
5115 sdump = message ("%d@%d@%d&",
5122 sdump = message ("%d@%d@%d@%d@%d",
5133 return (message ("%q|@%d|%q#%s",
5134 ctype_dump (v->utype),
5137 isParam ? cstring_undefined : v->uname));
5141 return (message ("%q|%q#%s",
5142 ctype_dump (v->utype),
5144 isParam ? cstring_undefined : v->uname));
5150 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5152 exkind_unparse (sRef_getExKind (v->sref)),
5153 ctype_unparse (v->utype), (int) v->utype));
5156 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5157 ctype_dump (v->utype),
5158 ynm_unparseCode (v->info->datatype->abs),
5159 ynm_unparseCode (v->info->datatype->mut),
5160 (int) sRef_getDefState (v->sref),
5161 (int) sRef_getNullState (v->sref),
5162 (int) sRef_getAliasKind (v->sref),
5163 (int) sRef_getExKind (v->sref),
5164 ctype_dump (v->info->datatype->type),
5168 cstring sdump, gdump, adump, xdump;
5169 alkind alk = sRef_getAliasKind (v->sref);
5170 exkind exk = sRef_getExKind (v->sref);
5172 if (sRef_getDefState (v->sref) == SS_DEFINED
5173 && !nstate_isKnown (sRef_getNullState (v->sref))
5174 && !exitkind_isKnown (v->info->fcn->exitCode)
5175 && v->info->fcn->specialCode == SPC_NONE
5176 && qual_isUnknown (v->info->fcn->nullPred))
5178 sdump = cstring_makeLiteral ("$");
5182 sdump = message ("@%d@%d@%d@%d@%x",
5183 (int) sRef_getDefState (v->sref),
5184 (int) sRef_getNullState (v->sref),
5185 (int) v->info->fcn->exitCode,
5186 (int) v->info->fcn->specialCode,
5187 qual_dump (v->info->fcn->nullPred));
5190 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5192 gdump = cstring_makeLiteral ("$");
5194 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5195 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5197 gdump = cstring_makeLiteral ("^");
5201 gdump = message ("@%s@%q@%s@%q",
5202 bool_dump (uentry_hasGlobs (v)),
5203 globSet_dump (uentry_getGlobs (v)),
5204 bool_dump (uentry_hasMods (v)),
5205 sRefSet_dump (uentry_getMods (v)));
5208 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5210 adump = cstring_makeLiteral ("$");
5214 adump = message ("@%d@%d", (int) alk, (int) exk);
5217 xdump = cstring_undefined;
5219 if (uentry_hasWarning (v))
5221 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5224 if (uentry_hasStateClauseList (v))
5226 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5229 return (message ("%q%q%q%q@%q%q#%s",
5230 ctype_dump (v->utype),
5234 typeIdSet_dump (uentry_accessType (v)),
5239 return (message ("%q@%q#%s",
5240 ctype_dump (v->utype),
5241 typeIdSet_dump (v->info->iter->access),
5244 return (message ("%q@%q#%s",
5245 ctype_dump (v->utype),
5246 typeIdSet_dump (uentry_accessType (v)),
5253 if (multiVal_isUnknown (uentry_getConstantValue (v))
5254 && typeIdSet_isEmpty (uentry_accessType (v))
5255 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5257 sdump = cstring_makeLiteral ("$");
5261 sdump = message ("@%q@%q@%d",
5262 multiVal_dump (uentry_getConstantValue (v)),
5263 typeIdSet_dump (uentry_accessType (v)),
5264 (int) sRef_getNullState (v->sref));
5267 return (message ("%q%q#%s",
5268 ctype_dump (v->utype),
5275 return (message ("%q@%q#%s",
5276 ctype_dump (v->utype),
5277 ctype_dump (v->info->datatype->type), v->uname));
5284 uentry_unparseAbbrev (uentry v)
5286 if (!uentry_isVariable (v))
5288 llcontbuglit ("uentry_unparseAbbrev: not variable");
5289 return uentry_unparse (v);
5292 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5296 uentry_unparse (uentry v)
5300 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5301 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5303 st = uentry_getName (v);
5305 if (cstring_isDefined (st))
5307 return (ctype_unparseDeclaration (v->utype, st));
5312 return (cstring_copy (ctype_unparse (v->utype)));
5317 uentry_unparseFull (uentry v)
5319 if (uentry_isUndefined (v))
5321 return (cstring_makeLiteral ("<undefined>"));
5327 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5328 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5329 ctype_unparse (v->utype),
5330 fileloc_unparse (uentry_whereSpecified (v)),
5331 fileloc_unparse (uentry_whereDeclared (v)),
5332 fileloc_unparse (uentry_whereDefined (v)));
5334 DPRINTF (("uentry: %s", res));
5336 if (uentry_isDatatype (v))
5338 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5341 (ctype_isDefined (v->info->datatype->type)
5342 ? v->info->datatype->type : ctype_unknown),
5343 ynm_unparse (v->info->datatype->mut),
5344 ynm_unparse (v->info->datatype->abs),
5345 sRef_unparseState (v->sref));
5347 else if (uentry_isFunction (v))
5349 res = message ("%q / sref: %q / mods: %q / "
5350 "globs: %q / clauses: %q / pre: %q / post: %q",
5352 sRef_unparseFull (v->sref),
5353 sRefSet_unparse (v->info->fcn->mods),
5354 globSet_unparse (v->info->fcn->globs),
5355 stateClauseList_unparse (v->info->fcn->specclauses),
5356 functionConstraint_unparse (v->info->fcn->preconditions),
5357 functionConstraint_unparse (v->info->fcn->postconditions));
5359 else if (uentry_isIter (v))
5361 res = message ("%q / sref: %q",
5363 sRef_unparseFull (v->sref));
5365 else if (uentry_isVariable (v))
5367 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5369 sRef_unparseFull (v->sref),
5370 (int) v->info->var->kind,
5371 (int) v->info->var->defstate,
5372 (int) v->info->var->nullstate,
5374 DPRINTF (("sref: [%p]", v->sref));
5375 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5376 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5378 else if (uentry_isConstant (v))
5380 res = message ("%q = %q / %q",
5381 res, multiVal_unparse (uentry_getConstantValue (v)),
5382 sRef_unparseFull (v->sref));
5386 res = message ("%q :: %q", res, uentry_unparse (v));
5393 bool uentry_hasAccessType (uentry e)
5395 if (uentry_isValid (e))
5400 return (!typeIdSet_isEmpty (e->info->iter->access));
5402 return (!typeIdSet_isEmpty (e->info->enditer->access));
5404 return (!typeIdSet_isEmpty (e->info->fcn->access));
5407 return (!typeIdSet_isEmpty (e->info->uconst->access));
5416 typeIdSet uentry_accessType (uentry e)
5418 if (uentry_isValid (e))
5423 return (e->info->iter->access);
5425 return (e->info->enditer->access);
5427 return (e->info->fcn->access);
5430 return (e->info->uconst->access);
5436 return typeIdSet_undefined;
5440 uentry_isVariable (uentry e)
5442 return (uentry_isVar (e));
5446 uentry_isSpecified (uentry e)
5448 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5452 uentry_isReallySpecified (uentry e)
5454 return (uentry_isValid (e)
5455 && fileloc_isRealSpec (e->whereSpecified));
5459 uentry_isVar (uentry e)
5461 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5465 uentry_isFakeTag (uentry e)
5467 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5471 uentry_isDatatype (uentry e)
5473 return (!uentry_isUndefined (e) &&
5474 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5475 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5479 uentry_setAbstract (uentry e)
5483 llassert (uentry_isDatatype (e)
5484 && (ynm_isMaybe (e->info->datatype->abs)));
5486 oldid = ctype_typeId (e->info->datatype->type);
5487 e->info->datatype->abs = YES;
5488 e->info->datatype->type = ctype_createAbstract (oldid);
5492 uentry_setConcrete (uentry e)
5494 llassert (uentry_isDatatype (e)
5495 && (ynm_isMaybe (e->info->datatype->abs)));
5497 e->info->datatype->abs = NO;
5501 uentry_isAbstractDatatype (uentry e)
5503 return (uentry_isDatatype (e)
5504 && (ynm_isOn (e->info->datatype->abs)));
5508 uentry_isMaybeAbstract (uentry e)
5510 return (uentry_isDatatype (e)
5511 && (ynm_isMaybe (e->info->datatype->abs)));
5515 uentry_isMutableDatatype (uentry e)
5517 bool res = uentry_isDatatype (e)
5518 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5524 uentry_isRefCountedDatatype (uentry e)
5526 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5530 uentry_isParam (uentry u)
5532 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5533 || u->info->var->kind == VKYIELDPARAM));
5537 uentry_isExpandedMacro (uentry u)
5539 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5543 uentry_isSefParam (uentry u)
5545 return (uentry_isVariable (u)
5546 && (u->info->var->kind == VKSEFPARAM
5547 || u->info->var->kind == VKREFSEFPARAM
5548 || u->info->var->kind == VKSEFRETPARAM
5549 || u->info->var->kind == VKREFSEFRETPARAM));
5553 uentry_isRefParam (uentry u)
5555 return (uentry_isVariable (u)
5556 && (u->info->var->kind == VKREFPARAM
5557 || u->info->var->kind == VKREFYIELDPARAM
5558 || u->info->var->kind == VKREFSEFPARAM
5559 || u->info->var->kind == VKREFSEFRETPARAM));
5563 uentry_isAnyParam (uentry u)
5565 return (uentry_isVariable (u)
5566 && ((u->info->var->kind == VKPARAM)
5567 || (u->info->var->kind == VKSEFPARAM)
5568 || (u->info->var->kind == VKYIELDPARAM)
5569 || (u->info->var->kind == VKRETPARAM)
5570 || (u->info->var->kind == VKSEFRETPARAM)));
5574 uentry_getDefState (uentry u)
5576 if (uentry_isValid (u))
5578 return (sRef_getDefState (u->sref));
5582 return (SS_UNKNOWN);
5587 uentry_isOut (uentry u)
5589 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5590 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5594 uentry_isPartial (uentry u)
5596 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5597 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5601 uentry_isStateSpecial (uentry u)
5603 return ((uentry_isVariable (u)
5604 && (u->info->var->defstate == SS_SPECIAL))
5605 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5608 exitkind uentry_getExitCode (uentry ue)
5610 if (uentry_isFunction (ue))
5612 return ue->info->fcn->exitCode;
5620 qual uentry_nullPred (uentry u)
5622 llassert (uentry_isRealFunction (u));
5624 if (uentry_isFunction (u))
5626 return (u->info->fcn->nullPred);
5630 return qual_createUnknown ();
5635 ** Note for variables, this is checking the declared state, not the current state.
5639 uentry_possiblyNull (uentry u)
5641 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5642 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5646 uentry_getAliasKind (uentry u)
5648 if (uentry_isValid (u))
5650 return (sRef_getAliasKind (uentry_getSref (u)));
5659 uentry_getExpKind (uentry u)
5661 if (uentry_isValid (u))
5663 return (sRef_getExKind (uentry_getSref (u)));
5672 uentry_isIter (uentry e)
5674 return (!uentry_isUndefined (e) && e->ukind == KITER);
5678 uentry_isEndIter (uentry e)
5680 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5684 uentry_isRealFunction (uentry e)
5686 return (uentry_isFunction (e) ||
5687 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5691 uentry_hasName (uentry e)
5693 if (uentry_isValid (e))
5695 cstring s = e->uname;
5697 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5698 || uentry_isFakeTag (e)));
5707 ** Returns true for fake tags.
5708 ** This is used for dumping the library
5711 bool uentry_hasRealName (uentry e)
5713 return (uentry_isValid (e)
5714 && cstring_isNonEmpty (e->uname)
5715 && !uentry_isGlobalMarker (e));
5719 /*@observer@*/ globSet
5720 uentry_getGlobs (uentry l)
5722 if (uentry_isInvalid (l))
5724 return globSet_undefined;
5727 if (l->ukind != KFCN)
5729 if (l->ukind != KITER && l->ukind != KENDITER)
5731 if (l->ukind == KVAR)
5733 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5735 ekind_unparse (l->ukind)));
5739 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5741 ekind_unparse (l->ukind)));
5744 return globSet_undefined;
5747 return l->info->fcn->globs;
5750 /*@observer@*/ sRefSet
5751 uentry_getMods (uentry l)
5753 llassert (uentry_isValid (l));
5755 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5757 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5758 return sRefSet_undefined;
5761 return l->info->fcn->mods;
5765 uentry_getKind (uentry e)
5767 llassert (uentry_isValid (e));
5772 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5774 llassert (uentry_isEitherConstant (e));
5775 return (sRef_getValue (e->sref));
5778 /*@observer@*/ uentryList
5779 uentry_getParams (uentry l)
5781 if (uentry_isInvalid (l)) return uentryList_undefined;
5788 ctype ct = l->utype;
5790 if (ctype_isFunction (ct))
5792 return (ctype_argsFunction (ct));
5796 return uentryList_undefined;
5801 ctype ct = l->utype;
5803 llassert (ctype_isFunction (ct));
5804 return (ctype_argsFunction (ct));
5811 /*@observer@*/ cstring
5812 uentry_rawName (uentry e)
5814 if (uentry_isValid (e))
5820 return cstring_undefined;
5825 uentry_getOptName (uentry e)
5827 cstring s = uentry_getName (e);
5829 if (cstring_isDefined (s))
5831 s = cstring_appendChar (s, ' ');
5838 uentry_getName (uentry e)
5840 cstring ret = cstring_undefined;
5842 if (uentry_isValid (e))
5844 if (uentry_isAnyTag (e))
5846 ret = fixTagName (e->uname);
5848 else if (uentry_isAnyParam (e))
5850 ret = cstring_copy (fixParamName (e->uname));
5854 ret = cstring_copy (e->uname);
5861 cstring uentry_observeRealName (uentry e)
5863 cstring ret = cstring_undefined;
5865 if (uentry_isValid (e))
5867 if (uentry_isAnyTag (e))
5869 if (isFakeTag (e->uname))
5871 ret = cstring_undefined;
5875 ret = plainTagName (e->uname);
5878 else if (uentry_isAnyParam (e))
5880 ret = fixParamName (e->uname);
5891 cstring uentry_getRealName (uentry e)
5893 if (uentry_isValid (e))
5895 if (uentry_isAnyTag (e))
5897 return (cstring_undefined);
5904 return cstring_undefined;
5907 ctype uentry_getType (uentry e)
5909 if (uentry_isValid (e))
5915 return ctype_unknown;
5919 fileloc uentry_whereLast (uentry e)
5923 if (uentry_isInvalid (e))
5925 return fileloc_undefined;
5928 loc = e->whereDefined;
5930 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5935 loc = uentry_whereDeclared (e);
5937 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5942 loc = uentry_whereSpecified (e);
5946 fileloc uentry_whereEither (uentry e)
5948 if (uentry_isInvalid (e)) return fileloc_undefined;
5950 if (fileloc_isDefined (e->whereDefined)
5951 && !fileloc_isExternal (e->whereDefined))
5953 return e->whereDefined;
5955 else if (fileloc_isDefined (e->whereDeclared))
5957 return e->whereDeclared;
5961 return e->whereSpecified;
5965 fileloc uentry_whereSpecified (uentry e)
5967 if (uentry_isInvalid (e)) return fileloc_undefined;
5969 return (e->whereSpecified);
5972 fileloc uentry_whereDefined (uentry e)
5974 if (uentry_isInvalid (e)) return fileloc_undefined;
5976 return (e->whereDefined);
5979 fileloc uentry_whereDeclared (uentry e)
5981 if (uentry_isInvalid (e)) return fileloc_undefined;
5983 return (e->whereDeclared);
5986 /*@observer@*/ fileloc
5987 uentry_whereEarliest (uentry e)
5989 if (uentry_isInvalid (e)) return fileloc_undefined;
5991 if (fileloc_isDefined (e->whereSpecified))
5993 return (e->whereSpecified);
5995 else if (fileloc_isDefined (e->whereDeclared))
5997 return (e->whereDeclared);
6001 return e->whereDefined;
6006 uentry_setFunctionDefined (uentry e, fileloc loc)
6008 if (uentry_isValid (e))
6010 llassert (uentry_isFunction (e));
6012 if (fileloc_isUndefined (e->whereDeclared))
6014 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6017 if (!fileloc_isDefined (e->whereDefined))
6019 e->whereDefined = fileloc_update (e->whereDefined, loc);
6025 uentry_setDeclDef (uentry e, fileloc f)
6027 uentry_setDeclared (e, f);
6029 if (!uentry_isFunction (e)
6030 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6032 uentry_setDefined (e, f);
6037 uentry_setDeclaredForce (uentry e, fileloc f)
6039 llassert (uentry_isValid (e));
6040 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6044 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6046 llassert (uentry_isValid (e));
6047 fileloc_free (e->whereDeclared);
6048 e->whereDeclared = f;
6052 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6056 llassert (uentry_isValid (e));
6057 oldloc = e->whereDeclared;
6059 if (fileloc_isDefined (oldloc))
6061 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6063 e->whereDeclared = f;
6064 fileloc_free (oldloc);
6073 e->whereDeclared = f;
6074 fileloc_free (oldloc);
6079 uentry_setDeclared (uentry e, fileloc f)
6083 llassert (uentry_isValid (e));
6084 oldloc = e->whereDeclared;
6086 if (fileloc_isDefined (oldloc))
6088 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6090 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6099 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6104 uentry_clearDefined (uentry e)
6106 if (uentry_isValid (e))
6108 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6113 uentry_setDefined (uentry e, fileloc f)
6117 llassert (uentry_isValid (e));
6118 oldloc = e->whereDefined;
6120 if (fileloc_isDefined (oldloc))
6122 if (fileloc_isLib (oldloc)
6123 || fileloc_isImport (oldloc)
6124 || fileloc_isBuiltin (oldloc)
6125 || fileloc_isPreproc (oldloc))
6127 e->whereDefined = fileloc_update (e->whereDefined, f);
6131 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6137 if (optgenerror (FLG_REDEF,
6138 message ("%s %q redefined",
6139 ekind_capName (e->ukind),
6140 uentry_getName (e)),
6143 llgenindentmsg (message ("Previous definition of %q",
6144 uentry_getName (e)),
6152 e->whereDefined = fileloc_update (e->whereDefined, f);
6157 uentry_isCodeDefined (uentry e)
6159 llassert (uentry_isValid (e));
6161 return (fileloc_isDefined (e->whereDefined));
6165 uentry_isDeclared (uentry e)
6167 if (uentry_isValid (e))
6169 return (fileloc_isDefined (e->whereDeclared));
6175 sRef uentry_getSref (uentry e)
6177 /* not true, used for functions too (but shouldn't be? */
6178 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6180 if (uentry_isInvalid (e)) return sRef_undefined;
6185 sRef uentry_getOrigSref (uentry e)
6187 /*@i523*/ /* evans 2001-09-09 - need to fix this
6188 if (uentry_isValid (e))
6190 if (uentry_isVariable (e))
6192 return e->info->var->origsref;
6196 sRef sr = sRef_copy (uentry_getSref (e));
6198 sRef_resetState (sr);
6199 sRef_clearDerived (sr);
6205 return sRef_undefined;
6209 if (uentry_isValid (e))
6211 sRef sr = sRef_copy (uentry_getSref (e));
6213 sRef_resetState (sr);
6214 sRef_clearDerived (sr);
6216 if (uentry_isVariable (e))
6218 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6219 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6226 return sRef_undefined;
6231 ** requires: uentry e is not in a hashed symbol table
6235 uentry_setName (uentry e, /*@only@*/ cstring n)
6237 llassert (uentry_isValid (e));
6239 cstring_free (e->uname);
6244 uentry_setType (uentry e, ctype t)
6246 if (uentry_isValid (e))
6249 sRef_setType (e->sref, t);
6254 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6257 ctype rettype = ctype_unknown;
6259 llassert (uentry_isValid (ue));
6261 uentry_convertVarFunction (ue);
6262 llassert (uentry_isFunction (ue));
6264 rct = ctype_realType (ue->utype);
6266 if (ctype_isFunction (rct))
6268 rettype = ctype_getReturnType (rct);
6271 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6275 uentry_setRefParam (uentry e)
6277 if (!uentry_isVar (e))
6279 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6283 if (e->info->var->kind == VKSEFPARAM)
6285 e->info->var->kind = VKREFSEFPARAM;
6287 else if (e->info->var->kind == VKSEFRETPARAM)
6289 e->info->var->kind = VKREFSEFRETPARAM;
6291 else if (e->info->var->kind == VKYIELDPARAM)
6293 e->info->var->kind = VKREFYIELDPARAM;
6297 e->info->var->kind = VKREFPARAM;
6303 uentry_setParam (uentry e)
6305 if (!uentry_isVar (e))
6307 if (uentry_isElipsisMarker (e))
6313 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6320 if (e->info->var->kind == VKYIELDPARAM
6321 || e->info->var->kind == VKSEFPARAM
6322 || e->info->var->kind == VKSEFRETPARAM)
6328 e->info->var->kind = VKPARAM;
6332 e->uname = makeParam (e->uname);
6333 cstring_free (oldname);
6338 uentry_setSref (uentry e, sRef s)
6340 if (uentry_isValid (e))
6342 if (sRef_isValid (e->sref))
6344 sRef_mergeStateQuietReverse (e->sref, s);
6348 e->sref = sRef_saveCopy (s);
6354 uentry_getAbstractType (uentry e)
6356 llassert (uentry_isDatatype (e));
6359 ** This assertion removed.
6360 ** Okay to have undefined type, for system types
6362 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6363 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6368 if (ctype_isUndefined (e->info->datatype->type))
6370 return ctype_unknown;
6374 ** Sadly, a kludge...
6377 if (ctype_isUserBool (e->info->datatype->type)) {
6381 return e->info->datatype->type;
6384 ctype uentry_getRealType (uentry e)
6387 typeId uid = USYMIDINVALID;
6389 if (uentry_isInvalid (e))
6391 return ctype_unknown;
6394 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6396 if (uentry_isAnyTag (e))
6401 if (uentry_isAbstractType (e))
6403 ct = uentry_getAbstractType (e);
6405 if (ctype_isManifestBool (ct)) {
6409 llassert (ctype_isUA (ct));
6411 uid = ctype_typeId (ct);
6413 if (!context_hasAccess (uid))
6419 ct = uentry_getType (e);
6421 /* if (ctype_isUserBool (ct)) return ct; */
6423 if (ctype_isManifestBool (ct)) {
6427 if (ctype_isUA (ct))
6429 usymId iid = ctype_typeId (ct);
6431 if (usymId_equal (iid, uid))
6433 llcontbug (message ("uentry_getRealType: recursive type! %s",
6434 ctype_unparse (ct)));
6439 /* evs 2000-07-25: possible infinite recursion ? */
6440 uentry ue2 = usymtab_getTypeEntry (iid);
6444 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6445 return ctype_unknown;
6448 return uentry_getRealType (ue2);
6457 ctype uentry_getForceRealType (uentry e)
6460 typeId uid = USYMIDINVALID;
6462 if (uentry_isInvalid (e))
6464 return ctype_unknown;
6467 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6469 if (uentry_isAnyTag (e))
6474 if (uentry_isAbstractType (e))
6476 ct = uentry_getAbstractType (e);
6477 llassert (ctype_isUA (ct));
6479 uid = ctype_typeId (ct);
6480 /* no check for access! */
6483 ct = uentry_getType (e);
6485 /* evs 2000-07-25 */
6486 /* if (ctype_isUserBool (ct)) return ct; */
6488 if (ctype_isManifestBool (ct)) {
6492 if (ctype_isUA (ct))
6494 usymId iid = ctype_typeId (ct);
6496 if (usymId_equal (iid, uid))
6498 llcontbug (message ("uentry_getRealType: recursive type! %s",
6499 ctype_unparse (ct)));
6504 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6513 uentry uentry_nameCopy (cstring name, uentry e)
6515 uentry enew = uentry_alloc ();
6517 llassert (uentry_isValid (e));
6519 /* enew->shallowCopy = FALSE; */
6520 enew->ukind = e->ukind;
6522 enew->utype = e->utype;
6523 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6524 enew->whereDefined = fileloc_copy (e->whereDefined);
6525 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6526 enew->sref = sRef_copy (e->sref);
6527 enew->used = e->used;
6529 enew->isPrivate = e->isPrivate;
6530 enew->hasNameError = FALSE;
6532 enew->uses = filelocList_new ();
6533 enew->warn = warnClause_undefined;
6535 enew->storageclass = e->storageclass;
6536 enew->info = uinfo_copy (e->info, e->ukind);
6542 uentry_setDatatype (uentry e, usymId uid)
6544 llassert (uentry_isDatatype (e));
6546 if (uentry_isAbstractType (e))
6548 e->info->datatype->type = ctype_createAbstract (uid);
6552 e->info->datatype->type = ctype_createUser (uid);
6557 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6558 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6561 llassert (uentry_isValid (e));
6563 if (fileloc_isSpec (f) || fileloc_isImport (f))
6565 e->whereSpecified = f;
6566 e->whereDeclared = fileloc_undefined;
6567 e->whereDefined = fileloc_undefined;
6571 e->whereSpecified = fileloc_undefined;
6572 e->whereDeclared = f;
6573 e->whereDefined = fileloc_undefined;
6576 llassert (fileloc_storable (f));
6580 ucinfo_free (/*@only@*/ ucinfo u)
6586 uvinfo_free (/*@only@*/ uvinfo u)
6588 /*drl7x added 6/29/01 */
6589 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6594 udinfo_free (/*@only@*/ udinfo u)
6600 ufinfo_free (/*@only@*/ ufinfo u)
6602 globSet_free (u->globs);
6603 sRefSet_free (u->mods);
6604 stateClauseList_free (u->specclauses);
6609 uiinfo_free (/*@only@*/ uiinfo u)
6615 ueinfo_free (/*@only@*/ ueinfo u)
6620 static /*@only@*/ ucinfo
6621 ucinfo_copy (ucinfo u)
6623 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6624 ret->access = u->access;
6625 ret->macro = u->macro;
6629 static /*@only@*/ uvinfo
6630 uvinfo_copy (uvinfo u)
6632 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6634 ret->kind = u->kind;
6635 ret->nullstate = u->nullstate;
6636 ret->defstate = u->defstate;
6637 ret->checked = u->checked;
6639 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6641 /* drl added 07-02-001 */
6642 /* copy null terminated information */
6644 if (u->bufinfo != NULL)
6646 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6647 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6648 ret->bufinfo->size = u->bufinfo->size;
6649 ret->bufinfo->len = u->bufinfo->len;
6654 ret->bufinfo = NULL;
6660 static /*@only@*/ udinfo
6661 udinfo_copy (udinfo u)
6663 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6667 ret->type = u->type;
6672 static /*@only@*/ ufinfo
6673 ufinfo_copy (ufinfo u)
6675 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6677 ret->hasGlobs = u->hasGlobs;
6678 ret->hasMods = u->hasMods;
6679 ret->exitCode = u->exitCode;
6680 ret->specialCode = u->specialCode;
6681 ret->nullPred = u->nullPred;
6682 ret->access = u->access;
6683 ret->globs = globSet_newCopy (u->globs);
6684 ret->mods = sRefSet_newCopy (u->mods);
6685 ret->defparams = u->defparams;
6686 ret->specclauses = stateClauseList_copy (u->specclauses);
6688 ret->preconditions = functionConstraint_copy (u->preconditions);
6689 ret->postconditions = functionConstraint_copy (u->postconditions);
6694 static /*@only@*/ uiinfo
6695 uiinfo_copy (uiinfo u)
6697 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6699 ret->access = u->access;
6700 ret->globs = globSet_newCopy (u->globs);
6701 ret->mods = sRefSet_newCopy (u->mods);
6706 static /*@only@*/ ueinfo
6707 ueinfo_copy (ueinfo u)
6709 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6711 ret->access = u->access;
6716 uinfo_free (uinfo u, ekind kind)
6721 case KCONST: ucinfo_free (u->uconst); break;
6722 case KVAR: uvinfo_free (u->var); break;
6726 case KDATATYPE: udinfo_free (u->datatype); break;
6727 case KFCN: ufinfo_free (u->fcn); break;
6728 case KITER: uiinfo_free (u->iter); break;
6729 case KENDITER: ueinfo_free (u->enditer); break;
6730 case KELIPSMARKER: break;
6731 case KINVALID: break;
6737 static /*@only@*/ /*@null@*/ uinfo
6738 uinfo_copy (uinfo u, ekind kind)
6740 if (kind == KELIPSMARKER || kind == KINVALID)
6746 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6751 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6752 case KVAR: ret->var = uvinfo_copy (u->var); break;
6756 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6757 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6758 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6759 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6767 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6769 filelocList_free (e->uses);
6770 cstring_free (e->uname);
6772 uinfo_free (e->info, e->ukind);
6774 fileloc_free (e->whereSpecified);
6775 fileloc_free (e->whereDefined);
6776 fileloc_free (e->whereDeclared);
6778 warnClause_free (e->warn);
6784 extern void uentry_markOwned (/*@owned@*/ uentry u)
6786 sfreeEventually (u);
6790 uentry_free (/*@only@*/ uentry e)
6792 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6794 uentry_reallyFree (e);
6799 ** For uentry's in the global or file scope
6803 uentry_freeComplete (/*@only@*/ uentry e)
6805 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6807 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6808 /*@i@*/ sRef_free (e->sref);
6809 e->sref = sRef_undefined;
6810 uentry_reallyFree (e);
6815 ** requires old->kind != new->kind, old->uname = new->uname
6819 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6821 llassert (uentry_isValid (old));
6822 llassert (uentry_isValid (unew));
6824 if (uentry_isEitherConstant (unew)
6825 && (fileloc_isPreproc (uentry_whereDeclared (old))
6826 || ctype_isUnknown (old->utype))
6827 && !uentry_isSpecified (old))
6835 if (!uentry_isDeclared (old))
6837 if (uentry_isSpecified (old))
6839 if (uentry_isSpecified (unew))
6841 llbuglit ("Respecification!");
6843 else if (uentry_isDeclared (unew))
6847 message ("%s %q inconsistently declared as %s: %t",
6848 ekind_capName (old->ukind),
6849 uentry_getName (unew),
6850 ekind_unparseLong (unew->ukind),
6852 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6854 uentry_showWhereLastKind (old);
6866 message ("%s %q inconsistently declared as %s: %t",
6867 ekind_capName (old->ukind),
6868 uentry_getName (unew),
6869 ekind_unparseLong (unew->ukind),
6871 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6873 uentry_showWhereLastKind (old);
6879 llassert (uentry_isDeclared (unew));
6881 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6882 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6886 message ("%s %q inconsistently redeclared as %s",
6887 ekind_capName (old->ukind),
6888 uentry_getName (unew),
6889 ekind_unparseLong (unew->ukind)),
6890 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6892 uentry_showWhereLastKind (old);
6898 uentry_updateInto (old, unew);
6902 ** def is the definition of spec, modifies spec
6904 ** reports any inconsistencies
6905 ** returns the summary of all available information
6906 ** if spec and def are inconsistent, def is returned
6910 uentry_showWhereLast (uentry spec)
6912 if (uentry_isValid (spec))
6914 if (fileloc_isDefined (spec->whereDefined)
6915 && !fileloc_isLib (spec->whereDefined)
6916 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6918 llgenindentmsg (message ("Previous definition of %q: %t",
6919 uentry_getName (spec),
6920 uentry_getType (spec)),
6921 uentry_whereDefined (spec));
6923 else if (uentry_isDeclared (spec))
6925 llgenindentmsg (message ("Previous declaration of %q: %t",
6926 uentry_getName (spec),
6927 uentry_getType (spec)),
6928 uentry_whereDeclared (spec));
6930 else if (uentry_isSpecified (spec))
6932 if (uentry_hasName (spec))
6934 llgenindentmsg (message ("Specification of %q: %t",
6935 uentry_getName (spec),
6936 uentry_getType (spec)),
6937 uentry_whereSpecified (spec));
6941 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6942 uentry_whereSpecified (spec));
6947 /* nothing to show */
6953 uentry_showWhereLastKind (uentry spec)
6955 if (uentry_isValid (spec))
6957 if (fileloc_isDefined (spec->whereDefined)
6958 && !fileloc_isLib (spec->whereDefined)
6959 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6961 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6962 uentry_getName (spec),
6963 ekind_unparseLong (spec->ukind),
6964 uentry_getType (spec)),
6965 uentry_whereDefined (spec));
6967 else if (uentry_isDeclared (spec))
6969 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6970 uentry_getName (spec),
6971 ekind_unparseLong (spec->ukind),
6972 uentry_getType (spec)),
6973 uentry_whereDeclared (spec));
6975 else if (uentry_isSpecified (spec))
6977 if (uentry_hasName (spec))
6979 llgenindentmsg (message ("Specification of %q as %s: %t",
6980 uentry_getName (spec),
6981 ekind_unparseLong (spec->ukind),
6982 uentry_getType (spec)),
6983 uentry_whereSpecified (spec));
6987 llgenindentmsg (message ("Specification as %s: %t",
6988 ekind_unparseLong (spec->ukind),
6989 uentry_getType (spec)),
6990 uentry_whereSpecified (spec));
6995 /* nothing to show */
7001 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7003 fileloc loc = uentry_whereDefined (ce);
7005 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7007 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7011 loc = uentry_whereSpecified (ce);
7013 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7015 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7020 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7022 if (uentry_isDeclared (spec))
7024 llgenindentmsg (message ("Previous declaration of %q: %q",
7025 uentry_getName (spec), extra),
7026 uentry_whereDeclared (spec));
7028 else if (uentry_isSpecified (spec))
7030 llgenindentmsg (message ("Specification of %q: %q",
7031 uentry_getName (spec), extra),
7032 uentry_whereSpecified (spec));
7036 cstring_free (extra);
7041 uentry_showWhereDeclared (uentry spec)
7043 if (uentry_isDeclared (spec))
7045 if (uentry_hasName (spec))
7047 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7048 uentry_whereDeclared (spec));
7052 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7055 else if (uentry_isSpecified (spec))
7057 if (uentry_hasName (spec))
7059 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7060 uentry_whereSpecified (spec));
7064 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7069 /* nothing to show */
7075 uentry_showWhereAny (uentry spec)
7077 if (uentry_isDeclared (spec))
7079 if (uentry_hasName (spec))
7081 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7082 uentry_whereDeclared (spec));
7086 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7089 else if (uentry_isSpecified (spec))
7091 if (uentry_hasName (spec))
7093 llgenindentmsg (message ("Specification of %q",
7094 uentry_getName (spec)),
7095 uentry_whereSpecified (spec));
7099 llgenindentmsg (cstring_makeLiteral ("Specification"),
7100 uentry_whereSpecified (spec));
7103 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7105 if (uentry_hasName (spec))
7107 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7108 uentry_whereDefined (spec));
7112 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7117 /* nothing to show */
7122 uentry_showWhereDefined (uentry spec)
7124 if (uentry_isCodeDefined (spec))
7126 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7127 uentry_whereDefined (spec));
7132 uentry_showWhereLastPlain (uentry spec)
7134 if (uentry_isDeclared (spec))
7136 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7137 uentry_whereDeclared (spec));
7139 else if (uentry_isSpecified (spec))
7141 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7142 uentry_whereSpecified (spec));
7150 uentry_showWhereLastVal (uentry spec, cstring val)
7152 if (uentry_isDeclared (spec))
7154 llgenindentmsg (message ("Previous declaration of %q: %s",
7155 uentry_getName (spec), val),
7156 uentry_whereDeclared (spec));
7158 else if (uentry_isSpecified (spec))
7160 llgenindentmsg (message ("Specification of %q: %s",
7161 uentry_getName (spec), val),
7162 uentry_whereSpecified (spec));
7170 uentry_showWhereSpecified (uentry spec)
7172 if (uentry_isSpecified (spec))
7174 if (uentry_hasName (spec))
7176 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7177 uentry_whereSpecified (spec));
7181 llgenindentmsg (cstring_makeLiteral ("Specification"),
7182 uentry_whereSpecified (spec));
7185 else if (uentry_isDeclared (spec))
7187 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7188 uentry_whereDeclared (spec));
7192 /* nothing to show */
7197 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7199 if (uentry_isSpecified (spec))
7201 if (uentry_hasName (spec))
7203 llgenindentmsg (message ("Specification of %q: %q",
7204 uentry_getName (spec), s),
7205 uentry_whereSpecified (spec));
7209 llgenindentmsg (message ("Specification: %q", s),
7210 uentry_whereSpecified (spec));
7213 else if (uentry_isDeclared (spec))
7215 llgenindentmsg (message ("Declaration of %q: %q",
7216 uentry_getName (spec), s),
7217 uentry_whereDeclared (spec));
7221 llgenindentmsg (message ("Previous: %q", s),
7222 uentry_whereLast (spec));
7231 checkStructConformance (uentry old, uentry unew)
7234 uentryList fold, fnew;
7237 ** requires: types of old and new are structs or unions
7240 llassert (uentry_isValid (old));
7241 llassert (uentry_isValid (unew));
7243 oldr = ctype_realType (old->utype);
7244 fold = ctype_getFields (oldr);
7246 newr = ctype_realType (unew->utype);
7247 fnew = ctype_getFields (newr);
7249 if (!uentryList_matchFields (fold, fnew))
7251 if (fileloc_equal (uentry_whereLast (old),
7252 uentry_whereLast (unew)))
7260 message ("%q %q %rdeclared with fields { %q }, %s "
7261 "with fields { %q }",
7262 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7263 uentry_getName (old),
7264 uentry_isDeclared (old),
7265 uentryList_unparseAbbrev (fnew),
7266 uentry_specOrDefName (old),
7267 uentryList_unparseAbbrev (fold)),
7268 uentry_whereDeclared (unew)))
7270 uentry_showWhereLastPlain (old);
7271 uentryList_showFieldDifference (fold, fnew);
7275 old->utype = unew->utype;
7280 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7283 ** requires old and new are enums
7286 ctype rold = ctype_realType (old->utype);
7287 ctype rnew = ctype_realType (unew->utype);
7288 enumNameList eold = ctype_elist (rold);
7289 enumNameList enew = ctype_elist (rnew);
7291 if (!enumNameList_match (eold, enew))
7295 message ("Enum %q declared with members { %q } but "
7296 "specified with members { %q }",
7297 uentry_getName (old),
7298 enumNameList_unparse (enew),
7299 enumNameList_unparse (eold)),
7300 uentry_whereDeclared (unew)))
7302 uentry_showWhereSpecified (old);
7303 old->utype = unew->utype;
7309 ** either oldCurrent or newCurrent may be undefined!
7313 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7314 uentry unew, uentry newCurrent, ctype newType,
7317 bool hasError = FALSE;
7319 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7321 if (uentry_hasName (newCurrent))
7323 hasError = optgenerror
7325 message ("Parameter %d, %q, of function %q has inconsistent type: "
7326 "declared %t, %s %t",
7327 paramno + 1, uentry_getName (newCurrent),
7328 uentry_getName (unew),
7329 newType, uentry_specOrDefName (old), oldType),
7330 uentry_whereDeclared (newCurrent));
7334 hasError = optgenerror
7336 message ("Parameter %d of function %q has inconsistent type: "
7337 "declared %t, %s %t",
7338 paramno + 1, uentry_getName (unew),
7339 newType, uentry_specOrDefName (old), oldType),
7340 uentry_whereDeclared (newCurrent));
7342 DPRINTF (("type: %s / %s",
7343 ctype_unparse (newType),
7344 ctype_unparse (ctype_realType (newType))));
7349 if (uentry_isDeclared (unew))
7351 hasError = optgenerror
7353 message ("Parameter %d of function %s has inconsistent type: "
7354 "declared %t, %s %t",
7355 paramno + 1, unew->uname,
7356 newType, uentry_specOrDefName (old), oldType),
7357 uentry_whereDeclared (unew));
7361 hasError = optgenerror
7363 message ("Parameter %d of function %s has inconsistent type: "
7364 "declared %t, %s %t",
7365 paramno + 1, unew->uname,
7366 newType, uentry_specOrDefName (old), oldType),
7367 uentry_whereDeclared (unew));
7373 DPRINTF (("Here: %s / %s",
7374 uentry_unparseFull (oldCurrent),
7375 uentry_unparseFull (newCurrent)));
7377 if (!uentry_isUndefined (oldCurrent))
7379 if (!uentry_isUndefined (newCurrent)
7380 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7382 uentry_showWhereLast (oldCurrent);
7386 uentry_showWhereLastPlain (old);
7389 uentry_setType (oldCurrent, newType);
7393 uentry_showWhereLastPlain (old);
7399 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7403 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7405 uentry_isDeclared (old),
7406 uentryList_size (uentry_getParams (unew)),
7407 uentry_specOrDefName (old),
7408 uentryList_size (uentry_getParams (old))),
7409 uentry_whereDeclared (unew)))
7411 uentry_showWhereLastPlain (old);
7416 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7420 message ("Function %s inconsistently %rdeclared to return %t",
7422 uentry_isDeclared (old),
7423 ctype_getReturnType (unew->utype)),
7424 uentry_whereDeclared (unew)))
7426 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7430 static cstring paramStorageName (uentry ue)
7432 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7435 static cstring fcnErrName (uentry ue)
7437 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7440 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7442 if (uentry_isVar (ue))
7444 return (checkedName (ue->info->var->checked));
7448 return (cstring_makeLiteralTemp ("<checked invalid>"));
7452 static cstring checkedName (chkind checked)
7456 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7457 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7458 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7459 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7460 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7466 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7471 if (uentry_isVar (unew))
7473 llassert (uentry_isVar (old));
7475 oldState = old->info->var->nullstate;
7476 newState = unew->info->var->nullstate;
7480 oldState = sRef_getNullState (old->sref);
7481 newState = sRef_getNullState (unew->sref);
7484 if (oldState == NS_ABSNULL)
7486 if (uentry_isVar (old))
7488 old->info->var->nullstate = newState;
7491 sRef_mergeNullState (old->sref, newState);
7493 else if (newState == NS_UNKNOWN)
7495 if (completeConform && newState != oldState
7496 && uentry_isReallySpecified (old))
7500 message ("%s %q specified as %s, but declared without %s qualifier",
7501 ekind_capName (unew->ukind),
7502 uentry_getName (unew),
7503 nstate_unparse (oldState),
7504 nstate_unparse (oldState)),
7505 uentry_whereDeclared (unew)))
7507 uentry_showWhereSpecified (old);
7511 if (uentry_isVar (unew))
7513 unew->info->var->nullstate = oldState;
7516 sRef_mergeNullState (unew->sref, oldState);
7518 else if (newState == NS_POSNULL)
7520 if (oldState == NS_MNOTNULL
7521 && (ctype_isUA (unew->utype)
7522 || (uentry_isFunction (unew)
7523 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7525 if (uentry_isVar (unew))
7527 unew->info->var->nullstate = oldState;
7530 sRef_mergeNullState (unew->sref, oldState);
7534 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7535 || oldState == NS_UNKNOWN)
7542 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7544 uentry_ekindName (unew),
7545 uentry_getName (unew),
7546 uentry_isDeclared (old),
7548 uentry_specOrDefName (old),
7549 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7550 uentry_whereDeclared (unew)))
7552 uentry_showWhereSpecified (old);
7557 if (uentry_isVar (old))
7559 old->info->var->nullstate = newState;
7562 sRef_mergeNullState (old->sref, newState);
7565 else if (newState == NS_MNOTNULL)
7567 if (oldState != NS_MNOTNULL)
7573 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7574 "%s without notnull qualifier",
7575 uentry_ekindName (unew),
7576 uentry_getName (unew),
7577 uentry_isDeclared (old),
7579 uentry_specOrDefName (old)),
7580 uentry_whereDeclared (unew)))
7582 uentry_showWhereSpecified (old);
7586 if (uentry_isVar (old))
7588 old->info->var->nullstate = newState;
7591 sRef_mergeNullState (old->sref, newState);
7596 if (uentry_isVar (unew))
7598 unew->info->var->nullstate = oldState;
7601 sRef_mergeNullState (unew->sref, oldState);
7606 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7607 bool mustConform, bool completeConform)
7613 if (uentry_isVar (old) && uentry_isVar (unew))
7615 oldState = old->info->var->defstate;
7616 newState = unew->info->var->defstate;
7621 oldState = sRef_getDefState (old->sref);
7622 newState = sRef_getDefState (unew->sref);
7625 if (newState != oldState
7626 && newState != SS_UNKNOWN
7627 && newState != SS_DEFINED)
7633 message ("%s %q inconsistently %rdeclared %s %s %s, "
7635 uentry_ekindName (unew),
7636 uentry_getName (unew),
7637 uentry_isDeclared (old),
7639 sstate_unparse (newState),
7640 paramStorageName (unew),
7641 uentry_specOrDefName (old),
7643 sstate_unparse (oldState),
7644 paramStorageName (unew)),
7645 uentry_whereDeclared (unew)))
7647 uentry_showWhereSpecified (old);
7651 if (vars) old->info->var->defstate = newState;
7652 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7657 && (newState != oldState) && (oldState != SS_DEFINED)
7658 && uentry_isReallySpecified (old))
7662 message ("%s %q specified as %s, but declared without %s qualifier",
7663 ekind_capName (unew->ukind),
7664 uentry_getName (unew),
7665 sstate_unparse (oldState),
7666 sstate_unparse (oldState)),
7667 uentry_whereDeclared (unew)))
7669 uentry_showWhereSpecified (old);
7673 if (vars) unew->info->var->defstate = oldState;
7674 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7679 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7680 bool mustConform, bool completeConform)
7685 oldKind = sRef_getAliasKind (old->sref);
7686 newKind = sRef_getAliasKind (unew->sref);
7688 if (alkind_isImplicit (newKind)
7689 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7691 if (completeConform && !alkind_equal (newKind, oldKind)
7692 && uentry_isReallySpecified (old))
7696 message ("%s %q specified as %s, but declared without "
7697 "explicit alias qualifier",
7698 ekind_capName (unew->ukind),
7699 uentry_getName (unew),
7700 alkind_unparse (oldKind)),
7701 uentry_whereDeclared (unew)))
7703 uentry_showWhereSpecified (old);
7708 ** This really shouldn't be necessary, but it is!
7709 ** Function params (?) use new here.
7712 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7716 if (alkind_isKnown (newKind))
7718 if (!alkind_equal (oldKind, newKind))
7720 if (alkind_isKnown (oldKind))
7725 message ("%s %q inconsistently %rdeclared %s %s storage, "
7727 uentry_ekindName (unew),
7728 uentry_getName (unew),
7729 uentry_isDeclared (old),
7731 alkind_unparse (newKind),
7732 uentry_specOrDefName (old),
7733 alkind_unparse (oldKind)),
7734 uentry_whereDeclared (unew)))
7736 uentry_showWhereSpecified (old);
7738 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7739 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7740 sRef_setAliasKind (old->sref, AK_ERROR,
7741 uentry_whereDeclared (unew));
7745 sRef_setAliasKind (old->sref, newKind,
7746 uentry_whereDeclared (unew));
7751 if (!(alkind_isImplicit (newKind)))
7754 !uentry_isFunction (unew) &&
7757 message ("%s %q inconsistently %rdeclared %s %s storage, "
7758 "implicitly %s as temp storage",
7759 uentry_ekindName (unew),
7760 uentry_getName (unew),
7761 uentry_isDeclared (old),
7763 alkind_unparse (newKind),
7764 uentry_specOrDefName (old)),
7765 uentry_whereDeclared (unew)))
7767 uentry_showWhereSpecified (old);
7771 sRef_setAliasKind (old->sref, newKind,
7772 uentry_whereDeclared (unew));
7774 else /* newKind is temp or refcounted */
7781 else /* newKind unknown */
7788 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7789 bool mustConform, bool completeConform)
7794 oldKind = sRef_getExKind (old->sref);
7795 newKind = sRef_getExKind (unew->sref);
7797 if (exkind_isKnown (newKind))
7799 if (oldKind != newKind)
7801 if (exkind_isKnown (oldKind))
7806 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7807 uentry_ekindName (unew),
7808 uentry_getName (unew),
7809 uentry_isDeclared (old),
7811 exkind_unparse (newKind),
7812 uentry_specOrDefName (old),
7813 exkind_unparse (oldKind)),
7814 uentry_whereDeclared (unew)))
7816 uentry_showWhereSpecified (old);
7819 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7826 message ("%s %q inconsistently %rdeclared %s %s, "
7827 "implicitly %s without exposure qualifier",
7828 uentry_ekindName (unew),
7829 uentry_getName (unew),
7830 uentry_isDeclared (old),
7832 exkind_unparse (newKind),
7833 uentry_specOrDefName (old)),
7834 uentry_whereDeclared (unew)))
7836 uentry_showWhereSpecified (old);
7839 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7845 if (completeConform && exkind_isKnown (oldKind)
7846 && uentry_isReallySpecified (old))
7850 message ("%s %q specified as %s, but declared without "
7851 "exposure qualifier",
7852 ekind_capName (unew->ukind),
7853 uentry_getName (unew),
7854 exkind_unparse (oldKind)),
7855 uentry_whereDeclared (unew)))
7857 uentry_showWhereSpecified (old);
7861 /* yes, this is necessary! (if its a param) */
7862 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7867 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7868 bool mustConform, /*@unused@*/ bool completeConform)
7870 valueTable newvals = sRef_getValueTable (unew->sref);
7872 if (valueTable_isDefined (newvals))
7874 DPRINTF (("Check meta state: %s -> %s",
7875 uentry_unparseFull (old),
7876 uentry_unparseFull (unew)));
7878 DPRINTF (("Check meta state refs: %s -> %s",
7879 sRef_unparseFull (old->sref),
7880 sRef_unparseFull (unew->sref)));
7882 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7885 ** Copy the new values into the old ref
7888 valueTable_elements (newvals, key, newval)
7890 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7891 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7893 llassert (metaStateInfo_isDefined (msinfo));
7895 if (stateValue_isUndefined (oldval))
7897 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7901 if (stateValue_isError (oldval))
7903 if (!stateValue_isError (newval))
7905 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7909 ; /* No change necessary. */
7914 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7916 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7922 if (!stateValue_isError (newval)
7923 && !stateValue_isImplicit (newval))
7925 if (uentry_hasName (unew)
7926 || !sRef_isParam (uentry_getSref (unew)))
7931 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7932 uentry_ekindName (unew),
7933 uentry_getName (unew),
7934 uentry_isDeclared (old),
7936 stateValue_unparseValue (newval, msinfo),
7937 uentry_specOrDefName (old),
7938 stateValue_unparseValue (oldval, msinfo)),
7939 uentry_whereDeclared (unew)))
7941 uentry_showWhereSpecified (old);
7949 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7950 uentry_ekindName (unew),
7951 sRef_getParam (uentry_getSref (unew)),
7952 uentry_isDeclared (old),
7954 stateValue_unparseValue (newval, msinfo),
7955 uentry_specOrDefName (old),
7956 stateValue_unparseValue (oldval, msinfo)),
7957 uentry_whereDeclared (unew)))
7959 uentry_showWhereSpecified (old);
7965 DPRINTF (("Updating!"));
7966 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7970 DPRINTF (("Values match"));
7974 } end_valueTable_elements ;
7979 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7980 /*@notnull@*/ uentry unew,
7981 bool mustConform, bool completeConform)
7983 checkDefState (old, unew, mustConform, completeConform);
7984 checkNullState (old, unew, mustConform, completeConform);
7985 checkAliasState (old, unew, mustConform, completeConform);
7986 checkExpState (old, unew, mustConform, completeConform);
7987 checkMetaState (old, unew, mustConform, completeConform);
7989 sRef_storeState (old->sref);
7990 sRef_storeState (unew->sref);
7994 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7996 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8001 llassert (uentry_isVar (old));
8002 llassert (uentry_isVar (unew));
8004 if (cstring_isEmpty (old->uname))
8006 cstring_free (old->uname);
8007 old->uname = cstring_copy (unew->uname);
8010 if (unew->info->var->kind == VKRETPARAM
8011 || unew->info->var->kind == VKSEFRETPARAM)
8013 if (old->info->var->kind != VKRETPARAM
8014 && old->info->var->kind != VKSEFRETPARAM)
8018 message ("Parameter %q inconsistently %rdeclared as "
8019 "returned parameter",
8020 uentry_getName (unew),
8021 uentry_isDeclared (old)),
8022 uentry_whereDeclared (unew)))
8024 uentry_showWhereSpecified (old);
8025 old->info->var->kind = unew->info->var->kind;
8031 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8033 if (old->info->var->kind != VKSEFPARAM
8034 && old->info->var->kind != VKSEFRETPARAM)
8038 message ("Parameter %qinconsistently %rdeclared as "
8040 uentry_getOptName (unew),
8041 uentry_isDeclared (old)),
8042 uentry_whereDeclared (unew)))
8044 uentry_showWhereSpecified (old);
8045 old->info->var->kind = unew->info->var->kind;
8050 if (old->info->var->kind == VKSPEC)
8052 old->info->var->kind = unew->info->var->kind;
8056 unew->info->var->kind = old->info->var->kind;
8059 if (unew->info->var->checked != CH_UNKNOWN
8060 && unew->info->var->checked != old->info->var->checked)
8062 if (old->info->var->checked == CH_UNKNOWN
8063 && !fileloc_isUser (uentry_whereLast (old)))
8071 message ("Variable %q inconsistently %rdeclared as "
8072 "%s parameter (was %s)",
8073 uentry_getName (unew),
8074 uentry_isDeclared (old),
8075 checkedName (unew->info->var->checked),
8076 checkedName (old->info->var->checked)),
8077 uentry_whereDeclared (unew)))
8079 uentry_showWhereSpecified (old);
8083 old->info->var->checked = unew->info->var->checked;
8088 && (old->info->var->checked != CH_UNKNOWN)
8089 && uentry_isReallySpecified (old))
8093 message ("%s %q specified as %s, but declared without %s qualifier",
8094 ekind_capName (unew->ukind),
8095 uentry_getName (unew),
8096 checkedName (old->info->var->checked),
8097 checkedName (old->info->var->checked)),
8098 uentry_whereDeclared (unew)))
8100 uentry_showWhereSpecified (old);
8104 unew->info->var->checked = old->info->var->checked;
8107 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8110 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8112 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8117 llassert (uentry_isVar (u1));
8118 llassert (uentry_isVar (u2));
8120 if (u1->info->var->kind != u2->info->var->kind) {
8121 if (u1->info->var->kind == VKSEFRETPARAM) {
8122 if (u2->info->var->kind == VKRETPARAM) {
8125 message ("Function types are inconsistent. Parameter %d is "
8126 "sef parameter, but non-sef parameter in "
8127 "assigned function: %s",
8128 paramno, exprNode_unparse (e)),
8130 } else if (u2->info->var->kind == VKSEFPARAM) {
8133 message ("Function types are inconsistent. Parameter %d is "
8134 "returns parameter, but non-returns parameter in "
8135 "assigned function: %s",
8136 paramno, exprNode_unparse (e)),
8141 message ("Function types are inconsistent. Parameter %d is "
8142 "sef returns parameter, but non-sef returns parameter in "
8143 "assigned function: %s",
8144 paramno, exprNode_unparse (e)),
8147 } else if (u1->info->var->kind == VKRETPARAM) {
8150 message ("Function types are inconsistent. Parameter %d is "
8151 "returns parameter, but non-returns parameter in "
8152 "assigned function: %s",
8153 paramno, exprNode_unparse (e)),
8155 } else if (u1->info->var->kind == VKSEFPARAM) {
8158 message ("Function types are inconsistent. Parameter %d is "
8159 "sef parameter, but non-sef parameter in "
8160 "assigned function: %s",
8161 paramno, exprNode_unparse (e)),
8164 if (u2->info->var->kind == VKSEFRETPARAM) {
8167 message ("Function types are inconsistent. Parameter %d is "
8168 "normal parameter, but sef returns parameter in "
8169 "assigned function: %s",
8170 paramno, exprNode_unparse (e)),
8172 } else if (u2->info->var->kind == VKSEFPARAM) {
8175 message ("Function types are inconsistent. Parameter %d is "
8176 "normal parameter, but sef parameter in "
8177 "assigned function: %s",
8178 paramno, exprNode_unparse (e)),
8180 } else if (u2->info->var->kind == VKRETPARAM) {
8183 message ("Function types are inconsistent. Parameter %d is "
8184 "normal parameter, but returns parameter in "
8185 "assigned function: %s",
8186 paramno, exprNode_unparse (e)),
8194 if (u1->info->var->defstate != u2->info->var->defstate)
8198 message ("Function types are inconsistent. Parameter %d is "
8199 "%s, but %s in assigned function: %s",
8201 sstate_unparse (u1->info->var->defstate),
8202 sstate_unparse (u2->info->var->defstate),
8203 exprNode_unparse (e)),
8207 if (u1->info->var->nullstate != u2->info->var->nullstate)
8211 message ("Function types are inconsistent. Parameter %d is "
8212 "%s, but %s in assigned function: %s",
8214 nstate_unparse (u1->info->var->nullstate),
8215 nstate_unparse (u2->info->var->nullstate),
8216 exprNode_unparse (e)),
8220 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8224 message ("Function types are inconsistent. Parameter %d is "
8225 "%s, but %s in assigned function: %s",
8227 alkind_unparse (sRef_getAliasKind (u1->sref)),
8228 alkind_unparse (sRef_getAliasKind (u2->sref)),
8229 exprNode_unparse (e)),
8233 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8237 message ("Function types are inconsistent. Parameter %d is "
8238 "%s, but %s in assigned function: %s",
8240 exkind_unparse (sRef_getExKind (u1->sref)),
8241 exkind_unparse (sRef_getExKind (u2->sref)),
8242 exprNode_unparse (e)),
8248 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8249 /*@notnull@*/ uentry unew,
8250 bool mustConform, /*@unused@*/ bool completeConform)
8252 uentryList oldParams = uentry_getParams (old);
8253 uentryList newParams = uentry_getParams (unew);
8254 ctype newType = unew->utype;
8255 ctype oldType = ctype_realType (old->utype);
8256 ctype oldRetType = ctype_unknown;
8257 ctype newRetType = ctype_unknown;
8259 DPRINTF (("Function conform: %s ==> %s",
8260 uentry_unparseFull (old),
8261 uentry_unparseFull (unew)));
8263 if (uentry_isForward (old))
8265 mustConform = FALSE;
8266 uentry_updateInto (old, unew);
8271 ** check return values
8274 if (ctype_isKnown (oldType))
8276 llassert (ctype_isFunction (oldType));
8277 oldRetType = ctype_getReturnType (oldType);
8280 if (ctype_isKnown (newType))
8282 llassert (ctype_isFunction (newType));
8283 newRetType = ctype_getReturnType (newType);
8286 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8287 && !ctype_matchDef (newRetType, oldRetType))
8289 if (mustConform) returnValueError (old, unew);
8293 if (ctype_isConj (newRetType))
8295 if (ctype_isConj (oldRetType))
8297 if (!ctype_sameAltTypes (newRetType, oldRetType))
8301 message ("Function %q inconsistently %rdeclared to "
8302 "return alternate types %s "
8303 "(types match, but alternates are not identical, "
8304 "so checking may not be correct)",
8305 uentry_getName (unew),
8306 uentry_isDeclared (old),
8307 ctype_unparse (newRetType)),
8308 uentry_whereDeclared (unew)))
8310 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8316 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8321 DPRINTF (("Before state: %s",
8322 uentry_unparseFull (old)));
8323 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8324 DPRINTF (("After state: %s",
8325 uentry_unparseFull (old)));
8327 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8329 if (exitkind_isKnown (unew->info->fcn->exitCode))
8333 message ("Function %q inconsistently %rdeclared using %s",
8334 uentry_getName (unew),
8335 uentry_isDeclared (old),
8336 exitkind_unparse (unew->info->fcn->exitCode)),
8337 uentry_whereDeclared (unew)))
8339 uentry_showWhereSpecified (old);
8344 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8348 if (!qual_isUnknown (unew->info->fcn->nullPred))
8350 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8354 message ("Function %q inconsistently %rdeclared using %s",
8355 uentry_getName (unew),
8356 uentry_isDeclared (old),
8357 qual_unparse (unew->info->fcn->nullPred)),
8358 uentry_whereDeclared (unew)))
8360 uentry_showWhereSpecified (old);
8366 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8369 if (unew->info->fcn->specialCode != SPC_NONE)
8371 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8375 message ("Function %q inconsistently %rdeclared using %s",
8376 uentry_getName (unew),
8377 uentry_isDeclared (old),
8378 specCode_unparse (unew->info->fcn->specialCode)),
8379 uentry_whereDeclared (unew)))
8381 uentry_showWhereSpecified (old);
8387 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8394 if (!uentryList_sameObject (oldParams, newParams)
8395 && (!uentryList_isMissingParams (oldParams)))
8397 if (!uentryList_isMissingParams (newParams))
8400 int nparams = uentryList_size (oldParams);
8401 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8403 if (nparams != uentryList_size (newParams))
8405 nargsError (old, unew);
8408 if (uentryList_size (newParams) < nparams)
8410 nparams = uentryList_size (newParams);
8413 while (paramno < nparams)
8415 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8416 uentry newCurrent = uentryList_getN (newParams, paramno);
8417 ctype oldCurrentType = uentry_getType (oldCurrent);
8418 ctype newCurrentType = uentry_getType (newCurrent);
8420 llassert (uentry_isValid (oldCurrent)
8421 && uentry_isValid (newCurrent));
8423 if (!uentry_isElipsisMarker (oldCurrent)
8424 && !uentry_isElipsisMarker (newCurrent))
8426 checkVarConformance (oldCurrent, newCurrent,
8427 mustConform, completeConform);
8432 if (uentry_hasName (oldCurrent)
8433 && uentry_hasName (newCurrent))
8435 cstring oldname = uentry_getName (oldCurrent);
8436 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8438 cstring nname = uentry_getName (newCurrent);
8441 if (cstring_isDefined (pfx)
8442 && cstring_equalPrefix (oldname, pfx))
8444 oname = cstring_suffix (oldname, cstring_length (pfx));
8449 /*@-branchstate@*/ } /*@=branchstate@*/
8451 if (cstring_isDefined (pfx)
8452 && cstring_equalPrefix (nname, pfx))
8454 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8459 /*@-branchstate@*/ } /*@=branchstate@*/
8461 if (!cstring_equal (oname, nnamefix))
8464 (FLG_DECLPARAMMATCH,
8465 message ("Definition parameter name %s does not match "
8466 "name of corresponding parameter in "
8469 uentry_whereLast (newCurrent)))
8471 uentry_showWhereLastPlain (oldCurrent);
8475 cstring_free (oldname);
8476 cstring_free (nname);
8480 if (!ctype_match (oldCurrentType, newCurrentType))
8482 paramTypeError (old, oldCurrent, oldCurrentType,
8483 unew, newCurrent, newCurrentType, paramno);
8487 if (ctype_isMissingParamsMarker (newCurrentType)
8488 || ctype_isElips (newCurrentType)
8489 || ctype_isMissingParamsMarker (oldCurrentType)
8490 || ctype_isElips (oldCurrentType))
8496 if (ctype_isConj (newCurrentType))
8498 if (ctype_isConj (oldCurrentType))
8500 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8504 message ("Parameter %q inconsistently %rdeclared with "
8505 "alternate types %s "
8506 "(types match, but alternates are not identical, "
8507 "so checking may not be correct)",
8508 uentry_getName (newCurrent),
8509 uentry_isDeclared (oldCurrent),
8510 ctype_unparse (newCurrentType)),
8511 uentry_whereDeclared (unew)))
8513 uentry_showWhereLastVal (oldCurrent,
8514 ctype_unparse (oldCurrentType));
8522 message ("Parameter %q inconsistently %rdeclared with "
8523 "alternate types %s",
8524 uentry_getName (newCurrent),
8525 uentry_isDeclared (oldCurrent),
8526 ctype_unparse (newCurrentType)),
8527 uentry_whereDeclared (unew)))
8529 uentry_showWhereLastVal (oldCurrent,
8530 ctype_unparse (oldCurrentType));
8537 if (ctype_isConj (oldCurrentType))
8539 uentry_setType (newCurrent, oldCurrentType);
8547 ** Forgot this! detected by splint:
8548 ** uentry.c:1257,15: Suspected infinite loop
8554 if (!uentryList_isMissingParams (newParams))
8556 if (ctype_isConj (oldRetType))
8558 old->utype = ctype_makeFunction (oldRetType,
8559 uentryList_copy (newParams));
8563 old->utype = unew->utype;
8567 checkGlobalsConformance (old, unew, mustConform, completeConform);
8568 checkModifiesConformance (old, unew, mustConform, completeConform);
8570 DPRINTF (("Before list: %s",
8571 uentry_unparseFull (old)));
8573 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8575 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8580 message ("Function %q redeclared using special clauses (can only "
8581 "be used in first declaration)",
8582 uentry_getName (unew)),
8583 uentry_whereDeclared (unew)))
8585 uentry_showWhereLast (old);
8589 /*@i23 need checking @*/
8591 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8595 /*@i43 should be able to append? @*/
8597 stateClauseList_checkEqual (old, unew);
8598 stateClauseList_free (unew->info->fcn->specclauses);
8599 unew->info->fcn->specclauses = stateClauseList_undefined;
8603 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8605 if (fileloc_isUndefined (old->whereDeclared))
8607 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8609 else if (fileloc_isUndefined (unew->whereDeclared))
8611 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8620 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8624 llassert (uentry_isValid (ue));
8625 llassert (uentry_isEitherConstant (ue));
8627 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8628 uval = uentry_getConstantValue (ue);
8630 if (multiVal_isDefined (uval))
8632 if (multiVal_isDefined (m))
8634 if (!multiVal_equiv (uval, m))
8638 message ("%s %q defined with inconsistent value: %q",
8639 ekind_capName (ue->ukind),
8640 uentry_getName (ue),
8641 multiVal_unparse (m)),
8644 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8652 uentry_setConstantValue (ue, m);
8657 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8660 bool typeError = FALSE;
8662 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8664 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8668 DPRINTF (("Check struct conformance: %s / %s",
8669 uentry_unparseFull (old),
8670 uentry_unparseFull (unew)));
8671 checkStructConformance (old, unew);
8676 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8678 llbug (message ("struct tags: bad types: %t / %t",
8679 old->utype, unew->utype));
8683 else if (uentry_isEnumTag (old))
8685 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8687 if (mustConform) checkEnumConformance (old, unew);
8691 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8693 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8694 ctype_unparse (unew->utype)));
8698 else if (!ctype_match (old->utype, unew->utype))
8700 DPRINTF (("Type mismatch: %s / %s",
8701 ctype_unparse (old->utype),
8702 ctype_unparse (unew->utype)));
8704 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8706 ctype realt = ctype_realType (unew->utype);
8708 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8710 unew->utype = ctype_bool;
8716 typeError = optgenerror
8718 message ("%q defined as %s", uentry_getName (old),
8719 ctype_unparse (realt)),
8720 uentry_whereDeclared (unew));
8728 ctype oldr = ctype_realType (old->utype);
8729 ctype newr = ctype_realType (unew->utype);
8731 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8733 checkStructConformance (old, unew);
8735 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8737 checkStructConformance (old, unew);
8739 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8741 checkEnumConformance (old, unew);
8743 else if (uentry_isConstant (old)
8744 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8746 /* okay...for now! (should check the type is reset later... */
8750 DPRINTF (("YABA!"));
8753 message ("%s %q %rdeclared with inconsistent type: %t",
8754 ekind_capName (unew->ukind),
8755 uentry_getName (unew),
8756 uentry_isDeclared (old),
8758 uentry_whereDeclared (unew)))
8760 uentry_showWhereLast (old);
8776 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8777 /*@notnull@*/ uentry unew,
8778 bool mustConform, bool completeConform)
8780 if (ctype_isDefined (unew->info->datatype->type))
8783 ** bool is hard coded here, since it is built into LCL.
8784 ** For now, we're stuck with LCL's types.
8787 if (ctype_isDirectBool (old->utype) &&
8788 cstring_equalLit (unew->uname, "bool"))
8790 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8791 evs 2000-07-25: removed
8793 unew->utype = ctype_bool;
8796 if (ctype_isUnknown (old->info->datatype->type))
8798 old->info->datatype->type = unew->info->datatype->type;
8802 DPRINTF (("Old: %s / New: %s",
8803 uentry_unparseFull (old),
8804 uentry_unparseFull (unew)));
8805 DPRINTF (("Types: %s / %s",
8806 ctype_unparse (old->info->datatype->type),
8807 ctype_unparse (unew->info->datatype->type)));
8809 if (ctype_matchDef (old->info->datatype->type,
8810 unew->info->datatype->type))
8819 ("Type %q %s with inconsistent type: %t",
8820 uentry_getName (unew),
8821 uentry_reDefDecl (old, unew),
8822 unew->info->datatype->type),
8823 uentry_whereDeclared (unew)))
8825 uentry_showWhereLastExtra
8826 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8829 old->info->datatype->type = unew->info->datatype->type;
8834 if (unew->info->datatype->abs != MAYBE)
8836 if (ynm_isOff (old->info->datatype->abs)
8837 && ynm_isOn (unew->info->datatype->abs))
8839 if (!ctype_isDirectBool (old->utype))
8844 ("Datatype %q inconsistently %rdeclared as abstract type",
8845 uentry_getName (unew),
8846 uentry_isDeclared (old)),
8847 uentry_whereDeclared (unew)))
8849 uentry_showWhereLastPlain (old);
8853 else if (ynm_isOn (old->info->datatype->abs)
8854 && ynm_isOff (unew->info->datatype->abs))
8856 if (!ctype_isDirectBool (old->utype))
8861 ("Datatype %q inconsistently %rdeclared as concrete type",
8862 uentry_getName (unew),
8863 uentry_isDeclared (old)),
8864 uentry_whereDeclared (unew)))
8866 uentry_showWhereLastPlain (old);
8877 if (ynm_isOn (old->info->datatype->abs))
8879 old->sref = unew->sref;
8880 unew->info->datatype->mut = old->info->datatype->mut;
8883 && uentry_isReallySpecified (old))
8888 ("Datatype %q specified as abstract, "
8889 "but abstract annotation not used in declaration",
8890 uentry_getName (unew)),
8891 uentry_whereDeclared (unew)))
8893 uentry_showWhereLastPlain (old);
8899 unew->info->datatype->abs = old->info->datatype->abs;
8901 if (ynm_isMaybe (unew->info->datatype->mut))
8903 if (completeConform && ynm_isOff (old->info->datatype->mut)
8904 && uentry_isReallySpecified (old))
8909 ("Datatype %q specified as immutable, "
8910 "but immutable annotation not used in declaration",
8911 uentry_getName (unew)),
8912 uentry_whereDeclared (unew)))
8914 uentry_showWhereLastPlain (old);
8918 unew->info->datatype->mut = old->info->datatype->mut;
8920 else if (ynm_isMaybe (old->info->datatype->mut))
8922 old->info->datatype->mut = unew->info->datatype->mut;
8926 if (ynm_isOn (old->info->datatype->abs))
8928 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8932 message ("Datatype %q inconsistently %rdeclared as immutable",
8933 uentry_getName (unew),
8934 uentry_isDeclared (old)),
8935 uentry_whereDeclared (unew)))
8937 uentry_showWhereLastPlain (old);
8942 if (ynm_isOff (old->info->datatype->mut)
8943 && ynm_isOn (unew->info->datatype->mut))
8947 message ("Datatype %q inconsistently %rdeclared as mutable",
8948 uentry_getName (unew),
8949 uentry_isDeclared (old)),
8950 uentry_whereDeclared (unew)))
8952 uentry_showWhereLastPlain (old);
8957 old->info->datatype->mut = unew->info->datatype->mut;
8960 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8964 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8965 /*@notnull@*/ uentry unew,
8967 /*@unused@*/ bool completeConform)
8969 multiVal oldval = uentry_getConstantValue (old);
8970 multiVal newval = uentry_getConstantValue (unew);
8972 if (multiVal_isDefined (oldval))
8974 if (multiVal_isDefined (newval))
8976 if (!multiVal_equiv (oldval, newval))
8981 message ("%s %q %rdeclared with inconsistent value: %q",
8982 ekind_capName (unew->ukind),
8983 uentry_getName (unew),
8984 uentry_isDeclared (old),
8985 multiVal_unparse (newval)),
8986 uentry_whereDeclared (unew)))
8988 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8992 uentry_setConstantValue (unew, multiVal_copy (oldval));
9001 uentry_setConstantValue (old, multiVal_copy (newval));
9006 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9007 /*@notnull@*/ uentry unew, bool mustConform,
9008 bool completeConform)
9010 bool typeError = FALSE;
9011 bool fcnConformance = FALSE;
9013 if (!ekind_equal (unew->ukind, old->ukind))
9016 ** okay, only if one is a function and the other is
9017 ** a variable of type function.
9020 if (unew->ukind == KENUMCONST
9021 && old->ukind == KCONST)
9023 old->ukind = KENUMCONST;
9027 if (unew->ukind == KFCN
9028 && old->ukind == KCONST
9029 && ctype_isUnknown (old->utype))
9032 ** When a function is defined with an unparam macro
9035 uentry_updateInto (old, unew);
9039 if (uentry_isExpandedMacro (old)
9040 && uentry_isEitherConstant (unew))
9042 uentry_updateInto (old, unew);
9046 if (uentry_isEndIter (unew))
9048 if (ctype_isUnknown (old->utype))
9050 if (!uentry_isSpecified (old)
9051 && uentry_isCodeDefined (unew))
9053 if (!fileloc_withinLines (uentry_whereDefined (old),
9054 uentry_whereDeclared (unew), 2))
9055 { /* bogus! will give errors if there is too much whitespace */
9059 ("Iterator finalized name %q does not match name in "
9060 "previous iter declaration (should be end_%q). This iter "
9061 "is declared at %q",
9062 uentry_getName (unew),
9063 uentry_getName (old),
9064 fileloc_unparse (uentry_whereDefined (old))),
9065 uentry_whereDeclared (old));
9069 uentry_updateInto (old, unew);
9074 KindConformanceError (old, unew, mustConform);
9078 if (uentry_isFunction (unew))
9080 if (uentry_isVariable (old))
9082 if (!ctype_isUnknown (old->utype))
9084 if (ctype_isFunction (old->utype))
9086 uentry_makeVarFunction (old);
9087 checkFunctionConformance (old, unew, mustConform,
9089 fcnConformance = TRUE;
9093 KindConformanceError (old, unew, mustConform);
9098 if (uentry_isExpandedMacro (old))
9100 if (fileloc_isUndefined (unew->whereDefined))
9102 unew->whereDefined = fileloc_update (unew->whereDefined,
9106 uentry_updateInto (old, unew);
9107 old->used = unew->used = TRUE;
9112 /* undeclared identifier */
9113 old->utype = unew->utype;
9114 uentry_makeVarFunction (old);
9115 checkFunctionConformance (old, unew, FALSE, FALSE);
9116 fcnConformance = TRUE;
9122 KindConformanceError (old, unew, mustConform);
9125 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9127 if (!ctype_isUnknown (unew->utype))
9129 if (ctype_isFunction (unew->utype))
9131 uentry_makeVarFunction (unew);
9132 checkFunctionConformance (old, unew, mustConform, completeConform);
9133 fcnConformance = TRUE;
9137 KindConformanceError (old, unew, mustConform);
9142 KindConformanceError (old, unew, mustConform);
9147 KindConformanceError (old, unew, mustConform);
9153 ** check parameter lists for functions
9154 ** (before type errors, to get better messages
9157 if (uentry_isFunction (old))
9159 checkFunctionConformance (old, unew, mustConform, completeConform);
9160 fcnConformance = TRUE;
9164 if (!ctype_isUndefined (old->utype))
9166 typeError = checkTypeConformance (old, unew, mustConform);
9173 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9175 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9178 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9180 DPRINTF (("Check datatype: %s / %s",
9181 uentry_unparseFull (old),
9182 uentry_unparseFull (unew)));
9184 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9187 if (uentry_isVariable (old) && uentry_isVariable (unew))
9190 !ctype_matchDef (old->utype, unew->utype))
9195 ("Variable %q %s with inconsistent type (arrays and pointers are "
9196 "not identical in variable declarations): %t",
9197 uentry_getName (unew),
9198 uentry_reDefDecl (old, unew),
9200 uentry_whereDeclared (unew)))
9202 uentry_showWhereLast (old);
9205 ** Avoid repeated errors.
9208 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9210 old->whereDefined = fileloc_update (old->whereDefined,
9218 checkVarConformance (old, unew, mustConform, completeConform);
9223 /* old->utype = unew->utype; */
9227 if (ctype_isConj (old->utype))
9229 if (ctype_isConj (unew->utype))
9231 if (!ctype_sameAltTypes (old->utype, unew->utype))
9235 message ("%s %q inconsistently %rdeclared with "
9236 "alternate types %s "
9237 "(types match, but alternates are not identical, "
9238 "so checking may not be correct)",
9239 ekind_capName (uentry_getKind (old)),
9240 uentry_getName (unew),
9241 uentry_isDeclared (old),
9242 ctype_unparse (unew->utype)),
9243 uentry_whereDeclared (unew)))
9245 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9249 old->utype = unew->utype;
9256 if (ctype_isUnknown (old->utype))
9258 old->utype = unew->utype;
9263 if (unew->ukind == old->ukind)
9266 unew->info = uinfo_copy (old->info, old->ukind);
9269 sRef_storeState (old->sref);
9270 sRef_storeState (unew->sref);
9273 static void uentry_mergeConstraints (uentry spec, uentry def)
9275 if (uentry_isFunction (def))
9277 DPRINTF (("Here: %s / %s",
9278 uentry_unparseFull (spec),
9279 uentry_unparseFull (def)));
9280 /* evans 2001-07-21 */
9281 llassert (uentry_isFunction (spec));
9283 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9285 if (fileloc_isXHFile (uentry_whereLast (def)))
9287 llassert (uentry_isFunction (spec));
9288 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9289 def->info->fcn->preconditions);
9291 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9297 /* Check if the constraints are identical */
9302 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9303 uentry_getName (spec),
9304 functionConstraint_unparse (spec->info->fcn->preconditions)),
9305 uentry_whereLast (def)))
9307 uentry_showWhereSpecified (spec);
9310 functionConstraint_free (spec->info->fcn->preconditions);
9311 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9314 def->info->fcn->preconditions = functionConstraint_undefined;
9317 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9319 if (fileloc_isXHFile (uentry_whereLast (def)))
9321 llassert (uentry_isFunction (spec));
9322 DPRINTF (("Post: %s /++/ %s",
9323 functionConstraint_unparse (spec->info->fcn->postconditions),
9324 functionConstraint_unparse (def->info->fcn->postconditions)));
9325 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9326 def->info->fcn->postconditions);
9327 def->info->fcn->postconditions = functionConstraint_undefined;
9328 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9335 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9336 uentry_getName (spec),
9337 functionConstraint_unparse (spec->info->fcn->postconditions)),
9338 uentry_whereLast (def)))
9340 uentry_showWhereSpecified (spec);
9343 functionConstraint_free (spec->info->fcn->postconditions);
9344 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9345 def->info->fcn->postconditions = functionConstraint_undefined;
9352 ** modifies spec to reflect def, reports any inconsistencies
9356 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9358 llassert (uentry_isValid (spec));
9359 llassert (uentry_isValid (def));
9360 llassert (cstring_equal (spec->uname, def->uname));
9362 if (uentry_isFunction (def))
9364 if (uentry_isConstant (spec))
9366 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9367 uentry_makeConstantFunction (spec);
9371 uentry_convertVarFunction (spec);
9374 llassert (uentry_isFunction (spec));
9377 DPRINTF (("Merge entries: %s / %s",
9378 uentry_unparseFull (spec),
9379 uentry_unparseFull (def)));
9381 uentry_mergeConstraints (spec, def);
9383 uentry_checkConformance (spec, def, TRUE,
9384 context_getFlag (FLG_NEEDSPEC));
9386 DPRINTF (("Merge entries after conform: %s / %s",
9387 uentry_unparseFull (spec),
9388 uentry_unparseFull (def)));
9390 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9393 ** okay, declarations conform. Propagate extra information.
9396 uentry_setDefined (spec, uentry_whereDefined (def));
9397 uentry_setDeclared (spec, uentry_whereDeclared (def));
9399 if (uentry_isStatic (def))
9403 message ("%s %q specified, but declared as static",
9404 ekind_capName (def->ukind),
9405 uentry_getName (def)),
9406 uentry_whereDeclared (def)))
9408 uentry_showWhereSpecified (spec);
9413 spec->storageclass = def->storageclass;
9416 sRef_storeState (spec->sref);
9418 spec->used = def->used || spec->used;
9419 spec->hasNameError |= def->hasNameError;
9423 if (!spec->hasNameError)
9425 uentry_checkName (spec);
9434 ** Can't generate function redeclaration errors when the
9435 ** entries are merged, since we don't yet know if its the
9436 ** definition of the function.
9440 uentry_clearDecl (void)
9442 posRedeclared = uentry_undefined;
9443 fileloc_free (posLoc);
9444 posLoc = fileloc_undefined;
9448 uentry_checkDecl (void)
9450 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9452 llassert (fileloc_isDefined (posLoc));
9454 if (uentry_isCodeDefined (posRedeclared))
9456 if (optgenerror (FLG_REDECL,
9457 message ("%s %q declared after definition",
9458 ekind_capName (posRedeclared->ukind),
9459 uentry_getName (posRedeclared)),
9462 llgenindentmsg (message ("Definition of %q",
9463 uentry_getName (posRedeclared)),
9464 posRedeclared->whereDeclared);
9469 if (optgenerror (FLG_REDECL,
9470 message ("%s %q declared more than once",
9471 ekind_capName (posRedeclared->ukind),
9472 uentry_getName (posRedeclared)),
9475 llgenindentmsg (message ("Previous declaration of %q",
9476 uentry_getName (posRedeclared)),
9477 posRedeclared->whereDeclared);
9482 fileloc_free (posLoc);
9483 posLoc = fileloc_undefined;
9484 posRedeclared = uentry_undefined;
9488 ** Redefinition of old as unew.
9489 ** modifies old to reflect unew, reports any inconsistencies
9493 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9495 fileloc olddef = uentry_whereDeclared (old);
9496 fileloc unewdef = uentry_whereDeclared (unew);
9500 DPRINTF (("uentry merge: %s / %s",
9501 uentry_unparseFull (old),
9502 uentry_unparseFull (unew)));
9505 fileloc_isUndefined (olddef)
9506 && fileloc_isDefined (uentry_whereDefined (old))
9507 && !uentry_isExpandedMacro (old);
9509 if (!context_getFlag (FLG_INCONDEFSLIB)
9510 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9512 mustConform = FALSE;
9519 llassert (uentry_isValid (old));
9520 llassert (uentry_isValid (unew));
9521 llassert (cstring_equal (old->uname, unew->uname));
9523 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9525 if (uentry_isConstant (old))
9527 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9528 uentry_makeConstantFunction (old);
9532 uentry_convertVarFunction (old);
9535 llassert (uentry_isFunction (old));
9538 DPRINTF (("uentry merge: %s / %s",
9539 uentry_unparseFull (old),
9540 uentry_unparseFull (unew)));
9542 if (uentry_isExtern (unew))
9544 uentry_setUsed (old, unewdef);
9548 ** should check old one was extern!
9551 if (uentry_isStatic (old))
9553 if (!(uentry_isStatic (unew)))
9557 message ("%s %q shadows static declaration",
9558 ekind_capName (unew->ukind),
9559 uentry_getName (unew)),
9562 uentry_showWhereLast (old);
9567 uentry_setDeclDef (old, unewdef);
9570 else if (uentry_isStatic (unew))
9572 uentry_setDeclDef (old, unewdef);
9574 else if (uentry_isExtern (old))
9576 uentry_setDeclared (old, unewdef);
9580 if (!uentry_isExtern (unew)
9581 && !uentry_isForward (old)
9582 && !fileloc_equal (olddef, unewdef)
9583 && !fileloc_isUndefined (olddef)
9584 && !fileloc_isUndefined (unewdef)
9585 && !fileloc_isBuiltin (olddef)
9586 && !fileloc_isBuiltin (unewdef)
9587 && !uentry_isYield (old)
9588 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9590 if (uentry_isVariable (old) || uentry_isVariable (unew))
9592 ; /* will report redeclaration error later */
9596 if (fileloc_isDefined (uentry_whereDefined (old)))
9600 message ("%s %q defined more than once",
9601 ekind_capName (unew->ukind),
9602 uentry_getName (unew)),
9603 uentry_whereLast (unew)))
9606 (message ("Previous definition of %q",
9607 uentry_getName (old)),
9608 uentry_whereLast (old));
9611 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9613 uentry_updateInto (old, unew);
9614 old->sref = sRef_saveCopy (old->sref);
9622 if (fileloc_isLib (olddef)
9623 || fileloc_isUndefined (olddef)
9624 || fileloc_isImport (olddef))
9626 if (uentry_isExtern (unew))
9628 if (uentry_isExtern (old)
9629 || (fileloc_isDefined (uentry_whereDeclared (old))
9630 && (!fileloc_equal (uentry_whereDeclared (old),
9631 uentry_whereDefined (old)))))
9635 message ("%s %q declared more than once",
9636 ekind_capName (unew->ukind),
9637 uentry_getName (unew)),
9638 unew->whereDeclared))
9641 (message ("Previous declaration of %q",
9642 uentry_getName (old)),
9643 old->whereDeclared);
9647 uentry_setExtern (old);
9651 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9657 DPRINTF (("uentry merge: %s / %s",
9658 uentry_unparseFull (old),
9659 uentry_unparseFull (unew)));
9661 uentry_mergeConstraints (old, unew);
9662 DPRINTF (("uentry merge: %s / %s",
9663 uentry_unparseFull (old),
9664 uentry_unparseFull (unew)));
9666 uentry_checkConformance (old, unew, mustConform, FALSE);
9667 DPRINTF (("uentry merge: %s / %s",
9668 uentry_unparseFull (old),
9669 uentry_unparseFull (unew)));
9671 old->used = old->used || unew->used;
9672 old->uses = filelocList_append (old->uses, unew->uses);
9673 unew->uses = filelocList_undefined;
9675 sRef_storeState (old->sref);
9676 sRef_storeState (unew->sref);
9680 old->whereDefined = fileloc_update (old->whereDefined,
9684 DPRINTF (("here: %s", uentry_unparseFull (old)));
9687 ** No redeclaration errors for functions here, since we
9688 ** don't know if this is the definition of the function.
9691 if (fileloc_isUser (old->whereDeclared)
9692 && fileloc_isUser (unew->whereDeclared)
9693 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9694 && !fileloc_isDefined (unew->whereDefined))
9696 if (uentry_isFunction (old))
9698 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9699 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9703 if (optgenerror (FLG_REDECL,
9704 message ("%s %q declared more than once",
9705 ekind_capName (unew->ukind),
9706 uentry_getName (unew)),
9707 unew->whereDeclared))
9709 llgenindentmsg (message ("Previous declaration of %q",
9710 uentry_getName (old)),
9711 old->whereDeclared);
9716 if (fileloc_isUndefined (old->whereDefined))
9718 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9722 if (!context_processingMacros ()
9723 && fileloc_isUser (old->whereDefined)
9724 && fileloc_isUser (unew->whereDefined)
9725 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9727 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9729 if (uentry_isVariable (unew)
9730 && uentry_isExtern (unew))
9732 if (optgenerror (FLG_REDECL,
9733 message ("%s %q declared after definition",
9734 ekind_capName (unew->ukind),
9735 uentry_getName (unew)),
9736 unew->whereDeclared))
9738 llgenindentmsg (message ("Definition of %q",
9739 uentry_getName (old)),
9745 if (optgenerror (FLG_REDEF,
9746 message ("%s %q redefined",
9747 ekind_capName (unew->ukind),
9748 uentry_getName (unew)),
9749 unew->whereDefined))
9751 llgenindentmsg (message ("Previous definition of %q",
9752 uentry_getName (old)),
9760 if (uentry_isExternal (unew))
9762 old->whereDefined = fileloc_createExternal ();
9765 if (unew->hasNameError)
9767 old->hasNameError = TRUE;
9772 if (!old->hasNameError)
9774 uentry_checkName (old);
9777 DPRINTF (("After: %s", uentry_unparseFull (old)));
9778 llassert (!ctype_isUndefined (old->utype));
9782 uentry_copyState (uentry res, uentry other)
9784 llassert (uentry_isValid (res));
9785 llassert (uentry_isValid (other));
9787 res->used = other->used;
9789 res->info->var->kind = other->info->var->kind;
9790 res->info->var->defstate = other->info->var->defstate;
9791 res->info->var->nullstate = other->info->var->nullstate;
9792 res->info->var->checked = other->info->var->checked;
9794 sRef_copyState (res->sref, other->sref);
9798 uentry_sameKind (uentry u1, uentry u2)
9800 if (uentry_isValid (u1) && uentry_isValid (u2))
9802 if (uentry_isVar (u1) && uentry_isVar (u2))
9804 ctype c1 = u1->utype;
9805 ctype c2 = u2->utype;
9807 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9810 ** both functions, or both not functions
9813 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9817 return ((u1->ukind == u2->ukind));
9824 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9827 llassert (uentry_isValid (unew));
9828 llassert (uentry_isValid (old));
9830 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9831 okind = unew->ukind;
9832 unew->ukind = old->ukind;
9833 llassert (cstring_equal (unew->uname, old->uname));
9834 unew->utype = old->utype;
9836 if (fileloc_isDefined (unew->whereSpecified)
9837 && !fileloc_isDefined (old->whereSpecified))
9839 ; /* Keep the old value */
9843 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9844 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9847 if (fileloc_isDefined (unew->whereDefined)
9848 && !fileloc_isDefined (old->whereDefined))
9850 ; /* Keep the old value */
9854 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9855 unew->whereDefined = fileloc_copy (old->whereDefined);
9858 if (fileloc_isDefined (unew->whereDeclared)
9859 && !fileloc_isDefined (old->whereDeclared))
9861 ; /* Keep the old value */
9865 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9866 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9869 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9871 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9872 unew->used = old->used;
9874 unew->isPrivate = old->isPrivate;
9875 unew->hasNameError = old->hasNameError;
9876 unew->uses = filelocList_append (unew->uses, old->uses);
9877 old->uses = filelocList_undefined;
9879 unew->storageclass = old->storageclass;
9880 uinfo_free (unew->info, okind);
9881 unew->info = uinfo_copy (old->info, old->ukind);
9886 uentry_copy (uentry e)
9888 if (uentry_isValid (e))
9890 uentry enew = uentry_alloc ();
9891 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9892 enew->ukind = e->ukind;
9893 enew->uname = cstring_copy (e->uname);
9894 enew->utype = e->utype;
9896 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9897 enew->whereDefined = fileloc_copy (e->whereDefined);
9898 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9900 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9901 enew->used = e->used;
9903 enew->isPrivate = e->isPrivate;
9904 enew->hasNameError = e->hasNameError;
9905 enew->uses = filelocList_undefined;
9907 enew->storageclass = e->storageclass;
9908 enew->info = uinfo_copy (e->info, e->ukind);
9909 enew->warn = warnClause_copy (e->warn);
9911 DPRINTF (("Here we are..."));
9912 DPRINTF (("original: %s", uentry_unparseFull (e)));
9913 DPRINTF (("copy: %s", uentry_unparse (enew)));
9914 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9919 return uentry_undefined;
9924 uentry_setState (uentry res, uentry other)
9926 llassert (uentry_isValid (res));
9927 llassert (uentry_isValid (other));
9929 llassert (res->ukind == other->ukind);
9930 llassert (res->ukind == KVAR);
9932 res->sref = sRef_saveCopy (other->sref);
9933 res->used = other->used;
9934 filelocList_free (res->uses);
9935 res->uses = other->uses;
9936 other->uses = filelocList_undefined;
9937 res->lset = other->lset;
9941 uentry_mergeUses (uentry res, uentry other)
9943 llassert (uentry_isValid (res));
9944 llassert (uentry_isValid (other));
9946 res->used = other->used || res->used;
9947 res->lset = other->lset || res->lset;
9948 res->uses = filelocList_append (res->uses, other->uses);
9949 other->uses = filelocList_undefined;
9954 ** This is a really ugly routine.
9956 ** gack...fix this one day.
9961 ** >> res is the false branch, other is the true branch (or continuation)
9963 ** >> res is the true branch, other is the false branch (or continutation)
9970 ** References not effected by res are propagated from other.
9974 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9975 bool flip, clause cl, fileloc loc)
9979 message ("%s %q is %s %s, but %s %s.",
9980 ekind_capName (res->ukind), uentry_getName (res),
9981 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9982 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9985 if (sRef_isDead (res->sref))
9987 sRef_showStateInfo (res->sref);
9989 else if (sRef_isKept (res->sref))
9991 sRef_showAliasInfo (res->sref);
9993 else /* dependent */
9995 sRef_showAliasInfo (res->sref);
9996 sRef_showAliasInfo (other->sref);
9999 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10003 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10005 alkind rk = sRef_getAliasKind (rs);
10006 alkind ok = sRef_getAliasKind (os);
10008 if (alkind_isError (rk) || alkind_isError (ok))
10014 return ((sRef_isDead (rs)
10015 || (alkind_isKept (rk) && !alkind_isKept (ok))
10016 || (alkind_isDependent (rk)
10017 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10018 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10023 branchStateAltError (/*@notnull@*/ uentry res,
10024 /*@notnull@*/ uentry other, bool flip,
10025 clause cl, fileloc loc)
10029 message ("%s %q is %s %s, but %s %s.",
10030 ekind_capName (res->ukind), uentry_getName (res),
10031 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10032 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10035 if (sRef_isDead (other->sref))
10037 sRef_showStateInfo (other->sref);
10041 sRef_showAliasInfo (other->sref);
10044 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10045 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10047 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10048 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10053 ** A reference is relevant for certain checks, only if it
10054 ** is not definitely null on this path (but not declared
10055 ** to always be null.)
10058 static bool uentry_relevantReference (sRef sr, bool flip)
10060 if (sRef_isKept (sr) || sRef_isDependent (sr))
10068 return !sRef_definitelyNullContext (sr);
10072 return !sRef_definitelyNullAltContext (sr);
10078 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10079 fileloc loc, bool mustReturn, bool flip, bool opt,
10082 sRef rs = res->sref;
10083 sRef os = other->sref;
10085 DPRINTF (("Merge alias states: %s / %s",
10086 uentry_unparseFull (res),
10087 uentry_unparseFull (other)));
10089 if (sRef_isValid (rs))
10093 if (uentry_incompatibleMemoryStates (rs, os))
10095 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10096 sRef_unparseFull (rs), sRef_unparseFull (os)));
10098 if (sRef_isThroughArrayFetch (rs)
10099 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10101 if (sRef_isKept (rs) || sRef_isKept (os))
10103 sRef_maybeKill (rs, loc);
10105 else if (sRef_isPossiblyDead (os))
10107 sRef_maybeKill (rs, loc);
10116 if (uentry_relevantReference (os, flip))
10118 if (sRef_isLocalParamVar (rs)
10119 && (sRef_isLocalState (os)
10120 || sRef_isDependent (os)))
10122 if (sRef_isDependent (rs))
10124 sRef_setDependent (os, loc);
10128 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10133 branchStateError (res, other, flip, cl, loc);
10138 if (sRef_isKept (rs))
10140 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10141 sRef_setKept (os, loc);
10146 if (uentry_incompatibleMemoryStates (os, rs))
10148 if (uentry_relevantReference (rs, !flip))
10150 if (sRef_isLocalParamVar (rs)
10151 && (sRef_isDependent (rs)
10152 || sRef_isLocalState (rs)))
10154 if (sRef_isDependent (os))
10156 sRef_setDependent (rs, loc);
10160 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10165 if (sRef_isParam (os))
10168 ** If the local variable associated
10169 ** with the param has the correct state,
10171 ** (e.g., free (s); s = new(); ...
10174 uentry uvar = usymtab_lookupSafe (other->uname);
10176 if (uentry_isValid (uvar)
10177 && ((sRef_isDead (os)
10178 && sRef_isOnly (uvar->sref))
10179 || (sRef_isDependent (os)
10180 && sRef_isOwned (uvar->sref))))
10186 branchStateAltError (res, other,
10192 DPRINTF (("Here: %s / %s",
10193 uentry_unparseFull (res),
10194 uentry_unparseFull (other)));
10196 branchStateAltError (res, other,
10203 if (sRef_isKept (os))
10205 sRef_setKept (rs, loc);
10211 DPRINTF (("Merge opt..."));
10212 sRef_mergeOptState (rs, os, cl, loc);
10213 DPRINTF (("Done!"));
10217 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10218 sRef_mergeState (rs, os, cl, loc);
10219 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10224 if (sRef_isModified (os))
10226 sRef_setModified (rs);
10231 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10235 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10236 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10238 valueTable rvalues;
10239 valueTable ovalues;
10241 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10249 rvalues = sRef_getValueTable (res->sref);
10250 ovalues = sRef_getValueTable (other->sref);
10252 if (valueTable_isUndefined (ovalues))
10254 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10257 else if (valueTable_isUndefined (rvalues))
10260 ** Copy values from other
10264 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10265 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10270 valueTable_elements (ovalues, fkey, fval) {
10272 metaStateInfo minfo;
10273 stateCombinationTable sctable;
10277 tval = valueTable_lookup (rvalues, fkey);
10279 DPRINTF (("Merge value: %s / %s X %s", fkey,
10280 stateValue_unparse (fval), stateValue_unparse (tval)));
10282 minfo = context_lookupMetaStateInfo (fkey);
10283 llassert (stateValue_isDefined (tval));
10285 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10287 DPRINTF (("Cannot find meta state for: %s", fkey));
10292 llassert (metaStateInfo_isDefined (minfo));
10294 if (stateValue_isError (fval)
10295 || sRef_definitelyNullContext (res->sref))
10297 sRef_setMetaStateValueComplete (res->sref,
10298 fkey, stateValue_getValue (fval),
10299 stateValue_getLoc (fval));
10300 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10302 else if (stateValue_isError (tval)
10303 || sRef_definitelyNullAltContext (other->sref))
10305 DPRINTF (("Other branch is definitely null!"));
10307 else if (sRef_isStateUndefined (res->sref)
10308 || sRef_isDead (res->sref))
10310 ; /* Combination state doesn't matter if it is undefined or dead */
10314 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10315 metaStateInfo_unparse (minfo),
10316 stateValue_unparse (fval),
10317 stateValue_unparse (tval)));
10319 DPRINTF (("state values: %d / %d",
10320 stateValue_getValue (fval), stateValue_getValue (tval)));
10322 sctable = metaStateInfo_getMergeTable (minfo);
10324 DPRINTF (("Merge table: %s",
10325 stateCombinationTable_unparse (sctable)));
10327 msg = cstring_undefined;
10329 nval = stateCombinationTable_lookup (sctable,
10330 stateValue_getValue (fval),
10331 stateValue_getValue (tval),
10334 DPRINTF (("nval: %d / %d / %d", nval,
10335 stateValue_getValue (fval), stateValue_getValue (tval)));
10337 if (nval == stateValue_error)
10339 /*@i32 print extra info for assignments@*/
10341 if (uentry_isGlobalMarker (res))
10346 ("Control branches merge with incompatible global states (%s and %s)%q",
10347 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10348 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10349 cstring_isDefined (msg)
10350 ? message (": %s", msg) : cstring_undefined),
10353 sRef_showMetaStateInfo (res->sref, fkey);
10354 sRef_showMetaStateInfo (other->sref, fkey);
10362 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10363 uentry_getName (res),
10364 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10365 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10366 cstring_isDefined (msg)
10367 ? message (": %s", msg) : cstring_undefined),
10370 sRef_showMetaStateInfo (res->sref, fkey);
10371 sRef_showMetaStateInfo (other->sref, fkey);
10372 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10373 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10374 DPRINTF (("Null: %s / %s",
10375 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10376 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10382 if (nval == stateValue_getValue (fval)
10383 && nval != stateValue_getValue (tval))
10385 loc = stateValue_getLoc (fval);
10387 else if (nval == stateValue_getValue (tval)
10388 && nval != stateValue_getValue (fval))
10390 loc = stateValue_getLoc (tval);
10397 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10398 && nval == stateValue_getValue (fval)
10399 && nval == stateValue_getValue (tval))
10405 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10409 } end_valueTable_elements ;
10415 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10416 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10417 bool flip, clause cl)
10419 if (cl == DOWHILECLAUSE)
10421 res->used = other->used || res->used;
10422 res->lset = other->lset || res->lset;
10423 res->uses = filelocList_append (res->uses, other->uses);
10424 other->uses = filelocList_undefined;
10428 if (sRef_isMacroParamRef (res->sref)
10429 && !uentry_isSefParam (other)
10430 && !uentry_isSefParam (res))
10432 bool hasError = FALSE;
10434 if (bool_equal (res->used, other->used))
10436 res->used = other->used;
10440 if (other->used && !flip)
10445 message ("Macro parameter %q used in true clause, "
10446 "but not in false clause",
10447 uentry_getName (res)),
10448 uentry_whereDeclared (res));
10455 message ("Macro parameter %q used in false clause, "
10456 "but not in true clause",
10457 uentry_getName (res)),
10458 uentry_whereDeclared (res));
10464 /* make it sef now, prevent more errors */
10465 res->info->var->kind = VKREFSEFPARAM;
10471 res->used = other->used || res->used;
10472 res->lset = other->lset || res->lset;
10473 res->uses = filelocList_append (res->uses, other->uses);
10474 other->uses = filelocList_undefined;
10480 uentry_mergeState (uentry res, uentry other, fileloc loc,
10481 bool mustReturn, bool flip, bool opt,
10484 llassert (uentry_isValid (res));
10485 llassert (uentry_isValid (other));
10487 llassert (res->ukind == other->ukind);
10488 llassert (res->ukind == KVAR);
10490 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10491 uentry_unparseFull (other)));
10493 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10494 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10495 uentry_mergeSetStates (res, other, loc, flip, cl);
10497 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10500 void uentry_setUsed (uentry e, fileloc loc)
10502 static bool firstTime = TRUE;
10503 static bool showUses = FALSE;
10504 static bool exportLocal = FALSE;
10506 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10510 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10512 showUses = context_getFlag (FLG_SHOWUSES);
10513 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10518 if (uentry_isValid (e))
10522 if (warnClause_isDefined (e->warn))
10524 flagSpec flg = warnClause_getFlag (e->warn);
10527 if (warnClause_hasMessage (e->warn))
10529 msg = cstring_copy (warnClause_getMessage (e->warn));
10533 msg = message ("Use of possibly dangerous %s",
10534 uentry_ekindNameLC (e));
10538 message ("%q: %q", msg, uentry_getName (e)),
10542 if (sRef_isMacroParamRef (e->sref))
10544 if (uentry_isYield (e) || uentry_isSefParam (e))
10550 if (context_inConditional ())
10554 message ("Macro parameter %q used in conditionally "
10555 "executed code (may or may not be "
10556 "evaluated exactly once)",
10557 uentry_getName (e)),
10560 e->info->var->kind = VKREFSEFPARAM;
10569 message ("Macro parameter %q used more than once",
10570 uentry_getName (e)),
10571 uentry_whereDeclared (e)))
10573 e->info->var->kind = VKREFSEFPARAM;
10580 if ((dp = uentry_directParamNo (e)) >= 0)
10582 uentry_setUsed (usymtab_getParam (dp), loc);
10587 if (!sRef_isLocalVar (e->sref))
10591 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10597 if (context_inMacro ())
10599 e->uses = filelocList_addUndefined (e->uses);
10603 e->uses = filelocList_addDifferentFile
10605 uentry_whereDeclared (e),
10614 bool uentry_isReturned (uentry u)
10616 return (uentry_isValid (u) && uentry_isVar (u)
10617 && (u->info->var->kind == VKRETPARAM
10618 || u->info->var->kind == VKSEFRETPARAM));
10623 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10625 llassert (uentry_isRealFunction (u));
10627 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10629 stateClauseList clauses = uentry_getStateClauseList (u);
10630 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10632 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10633 sRef_setAllocated (res, g_currentloc);
10635 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10636 stateClauseList_unparse (clauses)));
10639 ** This should be in exprNode_reflectEnsuresClause
10642 stateClauseList_postElements (clauses, cl)
10644 if (!stateClause_isGlobal (cl))
10646 sRefSet refs = stateClause_getRefs (cl);
10647 sRefMod modf = stateClause_getEffectFunction (cl);
10649 sRefSet_elements (refs, el)
10651 sRef base = sRef_getRootBase (el);
10653 if (sRef_isResult (base))
10657 sRef sr = sRef_fixBase (el, res);
10658 modf (sr, g_currentloc);
10665 } end_sRefSet_elements ;
10667 } end_stateClauseList_postElements ;
10675 sRefSet prefs = sRefSet_new ();
10676 sRef res = sRef_undefined;
10677 sRef tcref = sRef_undefined;
10678 sRef tref = sRef_undefined;
10681 params = uentry_getParams (u);
10684 ** Setting up aliases has to happen *after* setting null state!
10687 uentryList_elements (params, current)
10689 if (uentry_isReturned (current))
10691 if (exprNodeList_size (args) >= paramno)
10693 exprNode ecur = exprNodeList_nth (args, paramno);
10694 tref = exprNode_getSref (ecur);
10696 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10698 if (sRef_isValid (tref))
10700 tcref = sRef_copy (tref);
10702 if (sRef_isDead (tcref))
10704 sRef_setDefined (tcref, g_currentloc);
10705 sRef_setOnly (tcref, g_currentloc);
10708 if (sRef_isRefCounted (tcref))
10710 /* could be a new ref now (but only if its returned) */
10711 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10714 sRef_makeSafe (tcref);
10715 prefs = sRefSet_insert (prefs, tcref);
10721 } end_uentryList_elements ;
10723 if (sRefSet_size (prefs) > 0)
10725 nstate n = sRef_getNullState (u->sref);
10727 if (sRefSet_size (prefs) == 1)
10729 sRef rref = sRefSet_choose (prefs);
10731 res = sRef_makeType (sRef_getType (rref));
10732 sRef_copyState (res, tref);
10736 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10737 res = sRefSet_mergeIntoOne (prefs);
10740 if (nstate_isKnown (n))
10742 sRef_setNullState (res, n, g_currentloc);
10743 DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
10748 if (ctype_isFunction (u->utype))
10750 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10751 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10755 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10756 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10759 if (sRef_isRefCounted (res))
10761 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10765 if (sRef_getNullState (res) == NS_ABSNULL)
10767 ctype ct = ctype_realType (u->utype);
10769 if (ctype_isAbstract (ct))
10771 sRef_setNotNull (res, g_currentloc);
10775 if (ctype_isUser (ct))
10777 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10781 sRef_setNotNull (res, g_currentloc);
10786 if (sRef_isRefCounted (res))
10788 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10790 else if (sRef_isKillRef (res))
10792 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10799 ak = sRef_getAliasKind (res);
10801 if (alkind_isImplicit (ak))
10803 sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
10807 DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
10808 usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
10810 /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
10811 usymtab_addReallyForceMustAlias (res, tref);
10814 sRefSet_free (prefs);
10816 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10822 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10824 llassert (uentry_isRealFunction (u));
10826 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10828 stateClauseList clauses = uentry_getStateClauseList (u);
10829 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10831 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10832 sRef_setAllocated (res, g_currentloc);
10834 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10835 stateClauseList_unparse (clauses)));
10838 ** This should be in exprNode_reflectEnsuresClause
10841 stateClauseList_postElements (clauses, cl)
10843 if (!stateClause_isGlobal (cl))
10845 sRefSet refs = stateClause_getRefs (cl);
10846 sRefMod modf = stateClause_getEffectFunction (cl);
10848 sRefSet_elements (refs, el)
10850 sRef base = sRef_getRootBase (el);
10852 if (sRef_isResult (base))
10856 sRef sr = sRef_fixBase (el, res);
10857 modf (sr, g_currentloc);
10864 } end_sRefSet_elements ;
10866 } end_stateClauseList_postElements ;
10874 sRefSet prefs = sRefSet_new ();
10875 sRef res = sRef_undefined;
10878 params = uentry_getParams (u);
10880 uentryList_elements (params, current)
10882 if (uentry_isReturned (current))
10884 if (exprNodeList_size (args) >= paramno)
10886 exprNode ecur = exprNodeList_nth (args, paramno);
10887 sRef tref = exprNode_getSref (ecur);
10889 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10891 if (sRef_isValid (tref))
10893 sRef tcref = sRef_copy (tref);
10895 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10897 if (sRef_isDead (tcref))
10899 sRef_setDefined (tcref, g_currentloc);
10900 sRef_setOnly (tcref, g_currentloc);
10903 if (sRef_isRefCounted (tcref))
10905 /* could be a new ref now (but only if its returned) */
10906 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10909 sRef_makeSafe (tcref);
10910 prefs = sRefSet_insert (prefs, tcref);
10916 } end_uentryList_elements ;
10918 if (sRefSet_size (prefs) > 0)
10920 nstate n = sRef_getNullState (u->sref);
10922 if (sRefSet_size (prefs) == 1)
10924 res = sRefSet_choose (prefs);
10928 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10929 res = sRefSet_mergeIntoOne (prefs);
10932 if (nstate_isKnown (n))
10934 sRef_setNullState (res, n, g_currentloc);
10939 if (ctype_isFunction (u->utype))
10941 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10942 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10946 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10949 if (sRef_isRefCounted (res))
10951 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10956 if (sRef_getNullState (res) == NS_ABSNULL)
10958 ctype ct = ctype_realType (u->utype);
10960 if (ctype_isAbstract (ct))
10962 sRef_setNotNull (res, g_currentloc);
10966 if (ctype_isUser (ct))
10968 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10972 sRef_setNotNull (res, g_currentloc);
10977 if (sRef_isRefCounted (res))
10979 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10981 else if (sRef_isKillRef (res))
10983 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10990 ak = sRef_getAliasKind (res);
10992 if (alkind_isImplicit (ak))
10994 sRef_setAliasKind (res,
10995 alkind_fixImplicit (ak),
10999 sRefSet_free (prefs);
11001 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11006 static bool uentry_isRefCounted (uentry ue)
11008 ctype ct = uentry_getType (ue);
11010 if (ctype_isFunction (ct))
11012 return (ctype_isRefCounted (ctype_getReturnType (ct)));
11016 return (ctype_isRefCounted (ct));
11021 ** old was declared yield in the specification.
11022 ** new is declared in the iter implementation.
11025 void uentry_checkYieldParam (uentry old, uentry unew)
11029 llassert (uentry_isVariable (old));
11030 llassert (uentry_isVariable (unew));
11032 unew->info->var->kind = VKYIELDPARAM;
11033 (void) checkTypeConformance (old, unew, TRUE);
11034 checkVarConformance (old, unew, TRUE, FALSE);
11036 /* get rid of param marker */
11038 name = uentry_getName (unew);
11039 cstring_free (unew->uname);
11040 unew->uname = name;
11041 unew->info->var->kind = VKREFYIELDPARAM;
11043 uentry_setUsed (old, fileloc_undefined);
11044 uentry_setUsed (unew, fileloc_undefined);
11047 /*@observer@*/ cstring
11048 uentry_ekindName (uentry ue)
11050 if (uentry_isValid (ue))
11055 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11057 return cstring_makeLiteralTemp ("Datatype");
11059 return cstring_makeLiteralTemp ("Enum member");
11061 return cstring_makeLiteralTemp ("Constant");
11063 if (uentry_isParam (ue))
11065 return cstring_makeLiteralTemp ("Parameter");
11067 else if (uentry_isExpandedMacro (ue))
11069 return cstring_makeLiteralTemp ("Expanded macro");
11073 return cstring_makeLiteralTemp ("Variable");
11076 return cstring_makeLiteralTemp ("Function");
11078 return cstring_makeLiteralTemp ("Iterator");
11080 return cstring_makeLiteralTemp ("Iterator finalizer");
11082 return cstring_makeLiteralTemp ("Struct tag");
11084 return cstring_makeLiteralTemp ("Union tag");
11086 return cstring_makeLiteralTemp ("Enum tag");
11088 return cstring_makeLiteralTemp ("Optional parameters");
11093 return cstring_makeLiteralTemp ("<Undefined>");
11099 /*@observer@*/ cstring
11100 uentry_ekindNameLC (uentry ue)
11102 if (uentry_isValid (ue))
11107 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11109 return cstring_makeLiteralTemp ("datatype");
11111 return cstring_makeLiteralTemp ("enum member");
11113 return cstring_makeLiteralTemp ("constant");
11115 if (uentry_isParam (ue))
11117 return cstring_makeLiteralTemp ("parameter");
11119 else if (uentry_isExpandedMacro (ue))
11121 return cstring_makeLiteralTemp ("expanded macro");
11125 return cstring_makeLiteralTemp ("variable");
11128 return cstring_makeLiteralTemp ("function");
11130 return cstring_makeLiteralTemp ("iterator");
11132 return cstring_makeLiteralTemp ("iterator finalizer");
11134 return cstring_makeLiteralTemp ("struct tag");
11136 return cstring_makeLiteralTemp ("union tag");
11138 return cstring_makeLiteralTemp ("enum tag");
11140 return cstring_makeLiteralTemp ("optional parameters");
11145 return cstring_makeLiteralTemp ("<Undefined>");
11151 void uentry_setHasNameError (uentry ue)
11153 llassert (uentry_isValid (ue));
11155 ue->hasNameError = TRUE;
11158 void uentry_checkName (uentry ue)
11160 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11161 uentry_observeRealName (ue),
11162 bool_unparse (uentry_isVisibleExternally (ue))));
11164 if (uentry_isValid (ue)
11165 && !context_inXHFile ()
11166 && uentry_hasName (ue)
11167 && !uentry_isElipsisMarker (ue)
11168 && context_getFlag (FLG_NAMECHECKS)
11169 && !ue->hasNameError
11170 && !uentry_isEndIter (ue)
11171 && !fileloc_isBuiltin (uentry_whereLast (ue))
11172 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11174 DPRINTF (("Here..."));
11176 if (uentry_isPriv (ue))
11178 ; /* any checks here? */
11180 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11182 ; /* no errors for externals */
11188 if (uentry_isExpandedMacro (ue))
11194 if (uentry_isExpandedMacro (ue))
11198 else if (uentry_isVariable (ue))
11200 sRef sr = uentry_getSref (ue);
11202 if (sRef_isValid (sr))
11204 scope = sRef_getScope (sr);
11211 else if (uentry_isFunction (ue)
11212 || uentry_isIter (ue)
11213 || uentry_isEndIter (ue)
11214 || uentry_isConstant (ue))
11216 scope = uentry_isStatic (ue) ? fileScope : globScope;
11218 else /* datatypes, etc. must be global */
11223 usymtab_checkDistinctName (ue, scope);
11226 if (context_getFlag (FLG_CPPNAMES))
11231 if (scope == globScope)
11233 checkExternalName (ue);
11235 else if (scope == fileScope)
11237 checkFileScopeName (ue);
11241 checkLocalName (ue);
11245 checkAnsiName (ue);
11250 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11256 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11259 if (!context_inMacro ())
11261 sRef_setGlobalScopeSafe ();
11264 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11265 uentry_setUsed (ue, loc);
11267 tloc = fileloc_createExternal ();
11268 uentry_setDefined (ue, tloc);
11269 fileloc_free (tloc);
11270 uentry_setHasNameError (ue);
11272 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
11274 uentry_markOwned (ue);
11278 ue = usymtab_supReturnFileEntry (ue);
11281 if (!context_inMacro ())
11283 sRef_clearGlobalScopeSafe ();
11289 uentry uentry_makeGlobalMarker ()
11294 llassert (sRef_inGlobalScope ());
11296 ue = uentry_makeVariableAux
11297 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11298 sRef_makeGlobalMarker (),
11301 tloc = fileloc_createExternal ();
11302 uentry_setUsed (ue, tloc);
11303 uentry_setDefined (ue, tloc);
11304 fileloc_free (tloc);
11305 uentry_setHasNameError (ue);
11311 bool uentry_isGlobalMarker (uentry ue)
11313 return (uentry_isValid (ue)
11314 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11317 /* new start modifications */
11319 /* start modifications */
11321 requires: p_e is defined, is a ptr/array variable
11323 effects: sets the state of the variable
11327 void uentry_setPossiblyNullTerminatedState (uentry p_e)
11329 llassert (uentry_isValid (p_e));
11331 if (p_e->info != NULL)
11333 if (p_e->info->var != NULL)
11335 llassert (p_e->info->var->bufinfo != NULL);
11336 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11337 sRef_setPossiblyNullTerminatedState (p_e->sref);
11343 requires: p_e is defined, is a ptr/array variable
11345 effects: sets the size of the buffer
11348 void uentry_setNullTerminatedState (uentry p_e) {
11349 llassert (uentry_isValid (p_e));
11351 if (p_e->info != NULL)
11353 if (p_e->info->var != NULL)
11355 llassert (p_e->info->var->bufinfo != NULL);
11356 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11357 sRef_setNullTerminatedState (p_e->sref);
11363 requires: p_e is defined, is a ptr/array variable
11365 effects: sets the size of the buffer
11368 void uentry_setSize (uentry p_e, int size)
11370 if (uentry_isValid (p_e))
11372 if (p_e->info != NULL)
11374 if (p_e->info->var != NULL)
11376 llassert (p_e->info->var->bufinfo != NULL);
11377 p_e->info->var->bufinfo->size = size;
11378 sRef_setSize (p_e->sref, size);
11385 requires: p_e is defined, is a ptr/array variable
11387 effects: sets the length of the buffer
11390 void uentry_setLen (uentry p_e, int len)
11392 if (uentry_isValid (p_e))
11394 if (p_e->info != NULL
11395 && p_e->info->var != NULL)
11397 llassert (p_e->info->var->bufinfo != NULL);
11398 p_e->info->var->bufinfo->len = len;
11399 sRef_setLen (p_e->sref, len);
11406 bool uentry_hasMetaStateEnsures (uentry e)
11408 if (uentry_isValid (e) && uentry_isFunction (e))
11410 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11418 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11420 llassert (uentry_isValid (e) && uentry_isFunction (e));
11421 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11424 # ifdef DEBUGSPLINT
11427 ** For debugging only
11430 void uentry_checkValid (uentry ue)
11432 if (uentry_isValid (ue))
11434 sRef_checkCompletelyReasonable (ue->sref);