2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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@*/;
69 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
70 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
72 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
74 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
75 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
78 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
79 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
80 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
81 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
82 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
84 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
85 ctype p_oldType, /*@notnull@*/ uentry p_unew,
86 /*@notnull@*/ uentry p_newCurrent,
87 ctype p_newType, int p_paramno) /*@modifies g_warningstream@*/ ;
89 static /*@only@*/ /*@notnull@*/ uentry
90 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
91 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
93 static /*@only@*/ /*@notnull@*/ uentry
94 uentry_makeConstantAux (cstring p_n, ctype p_t,
95 /*@keep@*/ fileloc p_f, bool p_priv, bool p_macro,
96 /*@only@*/ multiVal p_m) /*@*/ ;
98 static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
100 if (uentry_isVariable (ue)
101 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
102 || ctype_isUnknown (uentry_getType (ue))))
104 uentry_makeVarFunction (ue);
108 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
110 uentry ue = (uentry) dmalloc (sizeof (*ue));
111 ue->warn = warnClause_undefined;
118 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
119 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
121 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
122 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
123 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
124 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
125 static void ucinfo_free (/*@only@*/ ucinfo p_u);
126 static void uvinfo_free (/*@only@*/ uvinfo p_u);
130 static /*@only@*/ cstring ancontext_unparse (ancontext an)
134 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
135 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
136 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
137 case AN_SUFIELD: return cstring_makeLiteral ("su field");
138 case AN_TDEFN: return cstring_makeLiteral ("type definition");
139 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
140 case AN_CONST: return cstring_makeLiteral ("constant");
146 static int annots[AN_LAST][QU_LAST];
147 static int decls[AN_LAST];
148 static int shdecls[AN_LAST];
149 static int idecls[AN_LAST];
155 for (i = AN_UNKNOWN; i < AN_LAST; i++)
161 for (j = QU_UNKNOWN; j < QU_LAST; j++)
168 static void tallyAnnot (ancontext ac, qual q)
182 for (j = QU_UNKNOWN; j < QU_LAST; j++)
187 for (i = AN_UNKNOWN; i < AN_LAST; i++)
193 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
194 ancontext_unparse (i),
195 decls[i], shdecls[i], idecls[i]);
197 totdecls += decls[i];
198 totshdecls += shdecls[i];
199 totidecls += idecls[i];
201 for (j = QU_UNKNOWN; j < QU_LAST; j++)
203 total[j] += annots[i][j];
204 alltotals += annots[i][j];
207 printf (" Allocation:\n");
211 for (j = QU_UNKNOWN; j < QU_LAST; j++)
213 if (qual_isAliasQual (j) && !qual_isUnique (j))
215 if (annots[i][j] > 0)
217 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
218 100.0 * (double)annots[i][j] / (double)decls[i]);
219 tmptot += annots[i][j];
224 printf (" Exposure:\n");
228 for (j = QU_UNKNOWN; j < QU_LAST; j++)
230 if (qual_isExQual (j))
232 if (annots[i][j] > 0)
234 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
235 100.0 * (double)annots[i][j] / (double)decls[i]);
236 tmptot += annots[i][j];
241 printf (" Definition:\n");
243 for (j = QU_UNKNOWN; j < QU_LAST; j++)
245 if (qual_isAllocQual (j))
247 if (annots[i][j] > 0)
249 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
250 100.0 * (double)annots[i][j] / (double)decls[i]);
257 for (j = QU_UNKNOWN; j < QU_LAST; j++)
259 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
261 if (annots[i][j] > 0)
263 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
264 100.0 * (double)annots[i][j] / (double)decls[i]);
273 for (j = QU_UNKNOWN; j < QU_LAST; j++)
277 for (i = AN_UNKNOWN; i < AN_LAST; i++)
279 if (annots[i][j] > 0)
288 printf ("Annotation: %s\n", qual_unparse (j));
290 for (i = AN_UNKNOWN; i < AN_LAST; i++)
292 if (annots[i][j] > 0)
294 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
301 printf ("All Contexts\n");
303 for (j = QU_UNKNOWN; j < QU_LAST; j++)
307 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
308 100.0 * (double)total[j] / (double)(totdecls));
313 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
315 extern void uentry_tallyAnnots (uentry u, ancontext kind)
317 alkind ak = sRef_getAliasKind (u->sref);
318 exkind ek = sRef_getExKind (u->sref);
319 nstate ns = sRef_getNullState (u->sref);
320 sstate ss = sRef_getDefState (u->sref);
321 bool recordUnknown = FALSE;
323 if (kind == AN_UNKNOWN)
331 else if (e == KCONST || e == KENUMCONST)
335 else if (e == KFCN || e == KITER)
337 uentryList params = uentry_getParams (u);
340 uentryList_elements (params, current)
342 if (uentry_isReturned (current))
346 if (!uentry_isElipsisMarker (current))
348 uentry_tallyAnnots (current, AN_FCNPARAM);
350 } end_uentryList_elements;
354 if (ctype_isFunction (u->utype)
356 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
358 recordUnknown = TRUE;
361 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
363 ctype t = ctype_realType (u->utype);
367 uentryList fields = ctype_getFields (t);
369 uentryList_elements (fields, current)
371 uentry_tallyAnnots (current, AN_SUFIELD);
373 } end_uentryList_elements;
377 if (ctype_isVisiblySharable (u->utype))
379 recordUnknown = TRUE;
387 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
389 recordUnknown = TRUE;
396 if (kind == AN_FCNRETURN)
410 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
415 if (ctype_isRealPointer (ctype_realType (u->utype)))
423 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
424 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
425 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
426 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
430 if (uentry_isReturned (u))
432 tallyAnnot (kind, QU_RETURNED);
438 if (ctype_isRefCounted (ctype_realType (u->utype))
439 || (ctype_isFunction (u->utype) &&
440 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
446 if (kind == AN_FCNPARAM)
448 tallyAnnot (kind, QU_TEMP);
450 else if (recordUnknown)
452 if (kind == AN_FCNRETURN)
455 tallyAnnot (kind, QU_UNKNOWN);
459 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
460 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
461 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
462 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
464 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
465 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
466 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
467 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
468 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
469 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
470 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
471 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
472 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
473 case AK_IMPDEPENDENT:
474 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
484 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
485 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
491 case NS_ERROR: break;
492 case NS_UNKNOWN: break;
493 case NS_NOTNULL: break;
494 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
495 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
496 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
497 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
499 case NS_ABSNULL: break;
505 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
509 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
510 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
511 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
512 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
513 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
519 static specCode specCode_fromInt (int i)
522 llassert (i >= SPC_NONE && i < SPC_LAST);
524 return ((specCode) i);
528 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
530 if (uentry_isDeclared (u))
532 return cstring_makeLiteralTemp ("previously declared");
536 return cstring_makeLiteralTemp ("specified");
540 /*@observer@*/ cstring uentry_specDeclName (uentry u)
542 if (uentry_isDeclared (u))
544 return cstring_makeLiteralTemp ("previous declaration");
548 return cstring_makeLiteralTemp ("specification");
552 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
554 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
556 return cstring_makeLiteralTemp ("redefined");
558 else if (uentry_isCodeDefined (unew))
560 return cstring_makeLiteralTemp ("defined");
562 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
564 return cstring_makeLiteralTemp ("redeclared");
568 return cstring_makeLiteralTemp ("declared");
572 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
574 if (uentry_isValid (ue))
576 functionConstraint constraint;
578 DPRINTF((message ("called uentry_getFcnPostconditions on %s",
579 uentry_unparse (ue) ) ) );
581 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
583 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
584 uentry_unparse (ue) ) ) );
585 if (!uentry_isFunction (ue) )
587 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
588 uentry_unparse (ue) ) ));
589 return constraintList_undefined;
593 return constraintList_undefined;
596 if (!uentry_isFunction(ue))
599 DPRINTF((message ("called uentry_getFunctionConditions on non function %s",
600 uentry_unparse (ue) ) ) );
601 return constraintList_undefined;
605 llassert (uentry_isFunction (ue));
609 constraint = ue->info->fcn->postconditions;
613 constraint = ue->info->fcn->preconditions;
616 return functionConstraint_getBufferConstraints (constraint);
619 return constraintList_undefined;
624 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
626 return uentry_getFunctionConditions (ue, FALSE);
633 constraintList uentry_getFcnPostconditions (uentry ue)
635 return uentry_getFunctionConditions (ue, TRUE);
638 static /*@only@*/ fileloc setLocation (void)
640 fileloc fl = context_getSaveLocation ();
642 if (fileloc_isDefined (fl))
648 return fileloc_copy (g_currentloc);
652 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
654 llassert (uentry_isEitherConstant (ue));
655 sRef_setValue (ue->sref, val);
658 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
660 fileloc loc = setLocation ();
661 uentry ue = uentry_makeConstant (n, t, loc);
663 ue->ukind = KENUMCONST;
664 uentry_setDefined (ue, loc);
668 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
670 fileloc loc = setLocation ();
671 uentry ue = uentry_makeConstant (n, t, loc);
672 ctype etype = exprNode_getType (expr);
674 if (!ctype_isRealInt (etype)) {
678 ("Value of enum member is not an integeral type (type %s): %s",
679 ctype_unparse (etype), exprNode_unparse (expr)),
680 exprNode_loc (expr));
683 ue->ukind = KENUMCONST;
684 uentry_setDefined (ue, loc);
688 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
690 uentry ue = uentry_makeConstant (n, t, loc);
692 ue->ukind = KENUMCONST;
696 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
698 return uentry_makeVariable (n, t, setLocation (), FALSE);
701 bool uentry_isUnnamedVariable (uentry ue)
703 return uentry_isVariable (ue) && cstring_isUndefined (ue->uname);
706 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
708 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
711 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
713 ctype ct = idDecl_getCtype (id);
714 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
715 MAYBE, qual_createUnknown (),
718 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
720 if (!qual_isEitherAbstract (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);
746 uentryList_elements (params, current)
750 if (uentry_isValid (current))
752 ctype ct = current->utype;
754 if (ctype_isFixedArray (ct))
756 if (ctype_isArray (ctype_baseArrayPtr (ct))
757 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
763 if (uentry_hasName (current))
766 (FLG_FIXEDFORMALARRAY,
767 message ("Function parameter %q declared as "
768 "manifest array (size constant is meaningless)",
769 uentry_getName (current)),
770 uentry_whereDeclared (current));
775 (FLG_FIXEDFORMALARRAY,
776 message ("Unnamed function parameter %d declared as "
777 "manifest array (size constant is meaningless)",
779 uentry_whereDeclared (current));
785 if (ctype_isArray (ct))
787 if (uentry_hasName (current))
791 message ("Function parameter %q declared as "
792 "array (treated as pointer)",
793 uentry_getName (current)),
794 uentry_whereDeclared (current));
800 message ("Unnamed function parameter %d declared as "
801 "array (treated as pointer)",
803 uentry_whereDeclared (current));
808 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
810 if (ctype_isAbstract (ct) &&
811 (isExt || (ctype_isAbstract (ctype_realType (ct))
812 && !context_hasFileAccess (ctype_typeId (ct)))))
817 ("Function %q declared with notnull parameter %q of abstract "
820 uentry_getName (current),
823 ("Since %s is an abstract type, notnull can only be "
824 "used for parameters if the function is static to a "
825 "module where %s is accessible.",
828 uentry_whereDeclared (current));
832 } end_uentryList_elements;
834 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
836 ctype ct = ue->utype;
838 if (ctype_isAbstract (ct)
839 && (isExt || (ctype_isAbstract (ctype_realType (ct))
840 && !context_hasFileAccess (ctype_typeId (ct)))))
845 ("%s %q declared %s notnull storage of abstract type %s",
846 ekind_capName (uentry_getKind (ue)),
851 ("Since %s is an abstract type, notnull can only be used "
852 "if it is static to a module where %s is accessible.",
855 uentry_whereDeclared (ue));
862 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
864 alkind ak = sRef_getAliasKind (ue->sref);
866 if (alkind_isRefCounted (ak))
868 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
872 if (alkind_isUnknown (ak))
874 exkind ek = sRef_getExKind (ue->sref);
876 if (exkind_isKnown (ek))
878 DPRINTF (("Setting imp dependent: %s",
879 uentry_unparseFull (ue)));
880 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
884 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
886 /* evans 2000-12-22 removed ctype_realType so it will
887 not apply to immutable abstract types. */
889 if (ctype_isVisiblySharable
890 (ctype_realType (ctype_getReturnType (ue->utype))))
892 if (uentryList_hasReturned (uentry_getParams (ue)))
898 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype))
899 || ctype_isNumAbstract (ctype_getReturnType (ue->utype)))
901 ; /* Immutable objects are not shared. */
905 sRef_setAliasKind (ue->sref, AK_IMPONLY,
907 DPRINTF (("Ret imp only: %s",
908 ctype_unparse (ctype_getReturnType (ue->utype))));
918 static /*@notnull@*/ uentry
919 uentry_makeFunctionAux (cstring n, ctype t,
921 /*@only@*/ globSet globs,
922 /*@only@*/ sRefSet mods,
923 /*@only@*/ warnClause warn,
924 /*@keep@*/ fileloc f, bool priv,
925 /*@unused@*/ bool isForward)
927 uentry e = uentry_alloc ();
930 llassert (warnClause_isUndefined (warn));
932 if (ctype_isFunction (t))
934 ret = ctype_getReturnType (t);
938 if (ctype_isKnown (t))
940 llbug (message ("not function: %s", ctype_unparse (t)));
947 if (fileloc_isSpec (f) || fileloc_isImport (f))
949 e->whereSpecified = f;
950 e->whereDeclared = fileloc_undefined;
954 e->whereSpecified = fileloc_undefined;
955 e->whereDeclared = f;
958 /* e->shallowCopy = FALSE; */
959 e->uname = cstring_copy (n);
961 e->storageclass = SCNONE;
963 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
965 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
967 if (ctype_isUA (ret))
969 sRef_setStateFromType (e->sref, ret);
974 e->uses = filelocList_new ();
976 e->hasNameError = FALSE;
980 e->info = (uinfo) dmalloc (sizeof (*e->info));
981 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
983 e->info->fcn->hasMods = sRefSet_isDefined (mods);
984 e->info->fcn->hasGlobs = globSet_isDefined (globs);
986 e->info->fcn->exitCode = XK_UNKNOWN;
987 e->info->fcn->nullPred = qual_createUnknown ();
988 e->info->fcn->specialCode = SPC_NONE;
990 e->info->fcn->access = access;
991 e->info->fcn->globs = globs;
992 e->info->fcn->defparams = uentryList_undefined;
994 sRef_setDefined (e->sref, f);
995 e->whereDefined = fileloc_undefined;
997 e->info->fcn->mods = sRefSet_undefined;
998 e->info->fcn->specclauses = NULL;
1001 e->info->fcn->preconditions = NULL;
1005 e->info->fcn->postconditions = NULL;
1008 checkGlobalsModifies (e, mods);
1009 e->info->fcn->mods = mods;
1014 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
1016 functionClauseList_elements (clauses, el)
1018 DPRINTF (("Reflect clause: %s on %s",
1019 functionClause_unparse (el), uentry_getName (ue)));
1021 if (functionClause_isNoMods (el))
1023 modifiesClause mel = functionClause_getModifies (el);
1025 if (uentry_hasGlobs (ue))
1030 ("No globals and modifies inconsistent to globals clause for %q: %q",
1031 uentry_getName (ue),
1032 globSet_unparse (uentry_getGlobs (ue))),
1033 modifiesClause_getLoc (mel));
1037 if (uentry_hasMods (ue))
1042 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1043 uentry_getName (ue),
1044 sRefSet_unparse (uentry_getMods (ue))),
1045 modifiesClause_getLoc (mel));
1048 uentry_setGlobals (ue, globSet_undefined);
1049 uentry_setModifies (ue, sRefSet_undefined);
1051 else if (functionClause_isGlobals (el))
1053 globalsClause glc = functionClause_getGlobals (el);
1055 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1056 globalsClause_unparse (glc)));
1058 if (uentry_hasGlobs (ue))
1063 ("Multiple globals clauses for %q: %q",
1064 uentry_getName (ue),
1065 globalsClause_unparse (glc)),
1066 cstring_makeLiteral ("Only one globals clause may be used. The second globals clause is ignored."),
1067 globalsClause_getLoc (glc));
1070 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1075 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
1076 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1077 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
1080 else if (functionClause_isModifies (el))
1082 modifiesClause mlc = functionClause_getModifies (el);
1084 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1086 if (uentry_hasMods (ue))
1094 ("Multiple modifies clauses for %s: %s",
1095 uentry_getName (ue),
1096 modifiesClause_unparse (mlc)),
1097 modifiesClause_getLoc (mlc)))
1099 llhint (message ("Previous modifies clause: ",
1100 sRefSet_unparse (uentry_getMods (ue))));
1106 uentry_combineModifies (ue, modifiesClause_takeMods (mlc));
1110 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1113 else if (functionClause_isEnsures (el))
1115 functionConstraint cl = functionClause_takeEnsures (el);
1116 DPRINTF (("Setting post: %s / %s",
1117 uentry_unparse (ue), functionConstraint_unparse (cl)));
1118 uentry_setPostconditions (ue, cl);
1120 else if (functionClause_isRequires (el))
1122 functionConstraint cl = functionClause_takeRequires (el);
1123 uentry_setPreconditions (ue, cl);
1125 else if (functionClause_isState (el))
1127 stateClause sc = functionClause_takeState (el);
1129 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1131 sRefSet rfs = stateClause_getRefs (sc);
1133 sRefSet_elements (rfs, s)
1135 if (sRef_isParam (s))
1138 ** Can't use requires on parameters
1142 (FLG_ANNOTATIONERROR,
1143 message ("Requires clauses for %q concerns parameters %q should be "
1144 "a parameter annotation instead: %q",
1145 uentry_unparse (ue),
1147 stateClause_unparse (sc)),
1148 stateClause_loc (sc));
1150 } end_sRefSet_elements ;
1153 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1154 uentry_addStateClause (ue, sc);
1156 else if (functionClause_isWarn (el))
1158 warnClause wc = functionClause_takeWarn (el);
1159 uentry_addWarning (ue, wc);
1163 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1165 } end_functionClauseList_elements ;
1167 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1168 stateClauseList_checkAll (ue);
1171 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1173 bool leaveFunc = FALSE;
1175 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1176 typeId_invalid, globSet_undefined,
1177 sRefSet_undefined, warnClause_undefined,
1180 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1183 ** This makes parameters names print out correctly.
1184 ** (But we might be a local variable declaration for a function type...)
1187 if (context_inFunctionLike ())
1189 DPRINTF (("Header: %s / %s",
1190 uentry_unparse (context_getHeader ()),
1191 idDecl_unparse (id)));
1195 context_enterFunctionDeclaration (ue);
1199 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1200 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1201 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1202 reflectImplicitFunctionQualifiers (ue, FALSE);
1203 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1204 uentry_reflectClauses (ue, idDecl_getClauses (id));
1205 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1207 if (!uentry_isStatic (ue)
1208 && cstring_equalLit (ue->uname, "main"))
1210 ctype typ = ue->utype;
1214 llassert (ctype_isFunction (typ));
1216 retval = ctype_getReturnType (typ);
1218 if (!ctype_isInt (retval))
1222 message ("Function main declared to return %s, should return int",
1223 ctype_unparse (retval)),
1224 uentry_whereDeclared (ue));
1227 args = ctype_argsFunction (typ);
1229 if (uentryList_isMissingParams (args)
1230 || uentryList_size (args) == 0)
1236 if (uentryList_size (args) != 2)
1240 message ("Function main declared with %d arg%&, "
1241 "should have 2 (int argc, char *argv[])",
1242 uentryList_size (args)),
1243 uentry_whereLast (ue));
1247 uentry arg = uentryList_getN (args, 0);
1248 ctype ct = uentry_getType (arg);
1250 if (!ctype_isInt (ct))
1254 message ("Parameter 1, %q, of function main declared "
1255 "with type %t, should have type int",
1256 uentry_getName (arg), ct),
1257 uentry_whereDeclared (arg));
1260 arg = uentryList_getN (args, 1);
1261 ct = uentry_getType (arg);
1263 if (ctype_isArrayPtr (ct)
1264 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1265 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1273 message ("Parameter 2, %q, of function main declared "
1274 "with type %t, should have type char **",
1275 uentry_getName (arg), ct),
1276 uentry_whereDeclared (arg));
1284 context_exitFunctionDeclaration ();
1290 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1292 alkind ak = sRef_getAliasKind (e->sref);
1294 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1295 && context_getFlag (FLG_PARAMIMPTEMP))
1297 exkind ek = sRef_getExKind (e->sref);
1299 if (exkind_isKnown (ek))
1301 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1302 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1303 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1307 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1308 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1313 static /*@only@*/ /*@notnull@*/ uentry
1314 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1315 /*@only@*/ fileloc loc, sstate defstate)
1317 cstring pname = makeParam (n);
1320 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1321 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1323 cstring_free (pname);
1324 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1325 uentry_implicitParamAnnots (e);
1326 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1328 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1330 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1331 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1332 e->info->var->defstate = defstate;
1335 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1340 uentry_setRefCounted (uentry e)
1342 if (uentry_isValid (e))
1344 uentry_setAliasKind (e, AK_REFCOUNTED);
1345 sRef_storeState (e->sref);
1350 uentry_setStatic (uentry c)
1352 if (uentry_isValid (c))
1354 alkind ak = sRef_getAliasKind (c->sref);
1355 c->storageclass = SCSTATIC;
1357 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1359 if (!alkind_isUnknown (ak)
1360 && !alkind_isStatic (ak))
1362 if (!(ctype_isRealPointer (uentry_getType (c)))
1363 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1364 && !alkind_isRefCounted (ak))
1366 if (alkind_isImplicit (ak)
1367 && alkind_isDependent (ak)
1368 && ctype_isArray (uentry_getType (c)))
1370 ; /* no error for observer arrays */
1376 message ("Static storage %q declared as %s",
1378 alkind_unparse (ak)),
1379 uentry_whereDeclared (c));
1385 if (alkind_isUnknown (ak)
1386 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1387 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1389 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1390 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1398 uentry_setExtern (uentry c)
1400 if (uentry_isValid (c))
1401 c->storageclass = SCEXTERN;
1405 uentry_setParamNo (uentry ue, int pno)
1407 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1408 sRef_setParamNo (ue->sref, pno);
1412 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1414 sRefSet_allElements (sr, el)
1416 sRef base = sRef_getRootBase (el);
1418 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1419 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1421 if (!globSet_member (ue->info->fcn->globs, base))
1423 if (uentry_hasGlobs (ue)
1424 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1427 (FLG_WARNMISSINGGLOBALS,
1429 ("Modifies list for %q uses global %q, "
1430 "not included in globals list.",
1431 uentry_getName (ue),
1432 sRef_unparse (base)),
1433 uentry_whereLast (ue)))
1435 uentry_showWhereSpecified (ue);
1439 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1441 if (sRef_isFileStatic (base))
1443 context_recordFileGlobals (ue->info->fcn->globs);
1447 } end_sRefSet_allElements;
1451 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1453 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1457 uentry_fixupSref (uentry ue)
1461 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1466 sr = uentry_getSref (ue);
1468 sRef_resetState (sr);
1469 sRef_clearDerived (sr);
1471 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1472 llassert (sRef_isValid (sr));
1474 if (uentry_isVariable (ue))
1476 /* removed this: no need to copy? ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1477 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1478 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1482 static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
1485 ** Okay to allow multiple clauses of the same kind.
1488 ue->info->fcn->specclauses =
1489 stateClauseList_add (ue->info->fcn->specclauses, sc);
1491 /* Will call checkAll to check later... */
1494 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1496 llassert (uentry_isFunction (ue));
1497 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1499 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1500 ue->info->fcn->specclauses = clauses;
1501 stateClauseList_checkAll (ue);
1502 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1506 ** Used for @modifies@ @endmodifies@ syntax.
1508 ** If ue is specified, sr must contain *only*:
1510 ** o file static globals
1511 ** o sRef's derived from modifies spec (i.e., more specific than
1512 ** what was specified)
1514 ** Otherwise, if sr has modifies it must match sr.
1516 ** If it doesn't have modifies, set them to sr.
1520 uentry_checkModifiesContext (void)
1522 if (sRef_modInFunction ())
1526 ("Modifies list not in function context. "
1527 "A modifies list can only appear following the parameter list "
1528 "in a function declaration or header."));
1537 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1539 if (!uentry_checkModifiesContext ())
1545 if (uentry_isValid (ue))
1547 if (uentry_isIter (ue))
1549 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1550 ue->info->iter->mods = sr;
1554 uentry_convertVarFunction (ue);
1555 llassertfatal (uentry_isFunction (ue));
1556 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1558 ue->info->fcn->mods = sr;
1559 ue->info->fcn->hasMods = TRUE;
1561 checkGlobalsModifies (ue, sr);
1564 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1566 ue->info->fcn->hasGlobs = TRUE;
1569 if (sRefSet_hasStatic (ue->info->fcn->mods))
1571 context_recordFileModifies (ue->info->fcn->mods);
1581 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1584 ** Function already has one modifies clause (possibly from
1585 ** a specification).
1588 if (!uentry_checkModifiesContext ())
1593 llassert (uentry_isValid (ue));
1595 if (uentry_isIter (ue))
1597 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1601 llassertfatal (uentry_isFunction (ue));
1602 llassert (ue->info->fcn->hasMods);
1604 checkGlobalsModifies (ue, sr);
1605 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1607 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1609 ue->info->fcn->hasGlobs = TRUE;
1613 if (sRefSet_hasStatic (ue->info->fcn->mods))
1615 context_recordFileModifies (ue->info->fcn->mods);
1619 bool uentry_hasWarning (uentry ue)
1621 return (uentry_isValid (ue)
1622 && warnClause_isDefined (ue->warn));
1625 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1627 llassert (uentry_isValid (ue));
1628 llassert (warnClause_isUndefined (ue->warn));
1633 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1635 if (sRef_modInFunction ())
1638 (message ("Precondition list not in function context. "
1639 "A precondition list can only appear following the parameter list "
1640 "in a function declaration or header."));
1642 /*@-mustfree@*/ return; /*@=mustfree@*/
1645 if (uentry_isValid (ue))
1647 uentry_convertVarFunction (ue);
1648 llassertfatal (uentry_isFunction (ue));
1650 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1652 /*drl oops this date is wronge...*/
1654 I changed this so it didn't appear as a Splint bug
1655 among other things this gets triggered when there is
1656 a function with two requires clauses. Now Splint
1657 prints an error and tries to conjoin the lists.
1660 (message ("Duplicate precondition list"
1661 "Attemping the conjoin the requires clauses"
1665 /* should conjoin constraints? */
1667 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1671 ue->info->fcn->preconditions = preconditions;
1676 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
1685 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1687 if (sRef_modInFunction ())
1690 (message ("Postcondition list not in function context. "
1691 "A postcondition list can only appear following the parameter list "
1692 "in a function declaration or header."));
1694 /*@-mustfree@*/ return; /*@=mustfree@*/
1697 if (uentry_isValid (ue))
1699 uentry_convertVarFunction (ue);
1700 llassertfatal (uentry_isFunction (ue));
1702 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1704 ue->info->fcn->postconditions = postconditions;
1708 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1713 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
1718 ** requires: new and old are functions
1722 checkGlobalsConformance (/*@notnull@*/ uentry old,
1723 /*@notnull@*/ uentry unew,
1724 bool mustConform, bool completeConform)
1726 bool hasInternalState = FALSE;
1728 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1730 if (globSet_isDefined (unew->info->fcn->globs))
1732 globSet_allElements (unew->info->fcn->globs, el)
1734 if (sRef_isFileStatic (el))
1736 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1738 if (sRef_isInvalid (sr))
1740 bool hasError = FALSE;
1742 if (!hasInternalState
1743 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1744 sRef_makeInternalState ()))
1745 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1746 sRef_makeSpecState ())))
1749 && !uentry_isStatic (old)
1752 message ("Globals list for %q includes internal state, %q, "
1753 "but %s without globals internalState.",
1754 uentry_getName (old),
1756 uentry_specOrDefName (old)),
1757 uentry_whereLast (unew)))
1759 uentry_showWhereSpecified (old);
1763 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1764 sRef_makeInternalState ());
1765 hasInternalState = TRUE;
1769 && fileloc_sameFile (uentry_whereDeclared (unew),
1770 uentry_whereDeclared (old)))
1775 message ("Function %q inconsistently %rdeclared (in "
1776 "same file) with file static global %q in "
1778 uentry_getName (unew),
1779 uentry_isDeclared (old),
1781 uentry_whereDeclared (unew)))
1783 uentry_showWhereSpecified (old);
1788 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1789 context_recordFileGlobals (old->info->fcn->globs);
1793 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1795 if (sRef_isInvalid (sr))
1800 message ("Function %q inconsistently %rdeclared with "
1801 "%q in globals list",
1802 uentry_getName (unew),
1803 uentry_isDeclared (old),
1805 uentry_whereDeclared (unew)))
1807 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1808 uentry_showWhereSpecified (old);
1813 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1819 ("Function %q global %q inconsistently "
1820 "%rdeclared as %qout global",
1821 uentry_getName (unew),
1823 uentry_isDeclared (old),
1824 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1825 uentry_whereDeclared (unew)))
1827 uentry_showWhereSpecified (old);
1832 } end_globSet_allElements ;
1834 if (completeConform)
1836 globSet_allElements (old->info->fcn->globs, el)
1838 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1840 if (sRef_isInvalid (sr))
1843 && uentry_isReallySpecified (old)
1846 message ("Function %q specified with %q in globals list, "
1847 "but declared without %q",
1848 uentry_getName (unew),
1851 uentry_whereDeclared (unew)))
1853 uentry_showWhereSpecified (old);
1856 } end_globSet_allElements;
1861 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1863 if (uentry_isReallySpecified (old)
1866 message ("%s %q specified with globals list, but "
1867 "declared with no globals",
1868 ekind_capName (unew->ukind),
1869 uentry_getName (unew)),
1870 uentry_whereDeclared (unew)))
1873 (message ("Specification globals: %q",
1874 globSet_unparse (old->info->fcn->globs)),
1875 uentry_whereSpecified (old));
1879 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1880 old->info->fcn->globs);
1885 ** new modifies list must be included by old modifies list.
1887 ** file static state may be added to new, if old has internal.
1891 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1892 bool mustConform, bool completeConform)
1895 bool changedMods = FALSE;
1896 bool modInternal = FALSE;
1898 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1900 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1901 newMods = unew->info->fcn->mods;
1903 if (sRefSet_isEmpty (newMods))
1905 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1906 && uentry_isReallySpecified (old))
1910 message ("%s %q specified with modifies clause, "
1911 "but declared with no modifies clause",
1912 ekind_capName (unew->ukind),
1913 uentry_getName (unew)),
1914 uentry_whereDeclared (unew)))
1916 llgenindentmsg (message ("Specification has modifies %q",
1917 sRefSet_unparse (old->info->fcn->mods)),
1918 uentry_whereSpecified (old));
1925 sRefSet_allElements (newMods, current)
1927 if (sRef_isValid (current))
1929 sRef rb = sRef_getRootBase (current);
1931 if (sRef_isFileStatic (rb))
1935 if (!sRefSet_isSameMember (old->info->fcn->mods,
1936 sRef_makeInternalState ())
1937 && !sRefSet_isSameMember (old->info->fcn->mods,
1938 sRef_makeSpecState ()))
1941 && !uentry_isStatic (old)
1945 ("Modifies list for %q includes internal state, "
1946 "but %s without modifies internal.",
1947 uentry_getName (old),
1948 uentry_specOrDefName (old)),
1949 uentry_whereLast (unew)))
1951 uentry_showWhereSpecified (old);
1954 old->info->fcn->mods =
1955 sRefSet_insert (old->info->fcn->mods,
1956 sRef_makeInternalState ());
1961 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1967 if (sRef_canModifyVal (current, old->info->fcn->mods))
1969 int size = sRefSet_size (old->info->fcn->mods);
1971 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1974 if (sRefSet_size (old->info->fcn->mods) != size)
1985 ("Modifies list for %q contains %q, not modifiable "
1987 uentry_getName (old),
1988 sRef_unparse (current),
1989 uentry_specDeclName (old)),
1990 uentry_whereLast (unew)))
1992 uentry_showWhereSpecified (old);
1997 } end_sRefSet_allElements;
1999 if (completeConform && uentry_isReallySpecified (old))
2001 sRefSet_allElements (old->info->fcn->mods, el)
2003 if (sRef_canModify (el, newMods))
2012 ("Specification modifies clause for %q contains %q, "
2013 "not included in declaration modifies clause",
2014 uentry_getName (old),
2016 uentry_whereLast (unew)))
2018 uentry_showWhereSpecified (old);
2021 } end_sRefSet_allElements ;
2025 ** Make sure file static elements will be removed.
2030 context_recordFileModifies (old->info->fcn->mods);
2035 uentry_checkMutableType (uentry ue)
2037 ctype ct = uentry_getType (ue);
2039 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2041 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2043 voptgenerror (FLG_MUTREP,
2044 message ("Mutable abstract type %q declared without pointer "
2045 "indirection: %t (violates assignment semantics)",
2046 uentry_getName (ue), ct),
2047 uentry_whereDeclared (ue));
2052 uentry_setMutable (uentry e)
2054 llassert (uentry_isDatatype (e));
2055 e->info->datatype->mut = YES;
2059 uentry_checkIterArgs (uentry ue)
2061 bool hasYield = FALSE;
2064 llassert (uentry_isIter (ue));
2066 args = uentry_getParams (ue);
2068 uentryList_elements (args, el)
2070 sstate ds = uentry_getDefState (el);
2072 if (uentry_isYield (el))
2077 if (sstate_isUnknown (ds))
2079 uentry_setDefState (el, SS_DEFINED);
2085 } end_uentryList_elements;
2089 voptgenerror (FLG_HASYIELD,
2090 message ("Iterator %q declared with no yield parameters",
2091 uentry_getName (ue)),
2092 uentry_whereDeclared (ue));
2097 chkind_fromQual (qual qel)
2099 if (qual_isChecked (qel))
2103 else if (qual_isCheckMod (qel))
2107 else if (qual_isCheckedStrict (qel))
2109 return CH_CHECKEDSTRICT;
2111 else if (qual_isUnchecked (qel))
2113 return CH_UNCHECKED;
2118 /*@notreached@*/ return CH_UNKNOWN;
2123 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2125 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2127 if (!uentry_isRefCounted (ue))
2130 (FLG_ANNOTATIONERROR,
2131 message ("Reference counting qualifier %s used on non-reference "
2132 "counted storage: %q",
2134 uentry_unparse (ue)),
2135 uentry_whereLast (ue));
2139 alkind ak = alkind_fromQual (qel);
2141 uentry_setAliasKind (ue, ak);
2144 else if (qual_isRefCounted (qel))
2146 ctype ct = ctype_realType (uentry_getType (ue));
2149 if (ctype_isPointer (ct)
2150 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2152 /* check there is a refs field */
2153 uentryList fields = ctype_getFields (rt);
2154 uentry refs = uentry_undefined;
2156 uentryList_elements (fields, field)
2158 if (uentry_isRefsField (field))
2160 if (uentry_isValid (refs))
2163 (FLG_ANNOTATIONERROR,
2164 message ("Reference counted structure type %s has "
2165 "multiple refs fields: %q and %q",
2167 uentry_getName (refs),
2168 uentry_getName (field)),
2169 uentry_whereLast (field));
2174 } end_uentryList_elements;
2176 if (uentry_isInvalid (refs))
2180 message ("Reference counted structure type %s has "
2182 ctype_unparse (ct)),
2184 ("To count reference, the structure must have a field named "
2185 "refs of type int."),
2188 else if (!ctype_isInt (uentry_getType (refs)))
2191 (FLG_ANNOTATIONERROR,
2192 message ("Reference counted structure type %s refs field has "
2193 "type %s (should be int)", ctype_unparse (ct),
2194 ctype_unparse (uentry_getType (refs))),
2195 uentry_whereLast (refs));
2199 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2200 uentry_whereDeclared (ue));
2205 if ((ctype_isPointer (ct)
2206 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2207 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2209 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2210 uentry_whereDeclared (ue));
2215 (FLG_ANNOTATIONERROR,
2216 message ("Non-pointer to structure type %s declared with "
2217 "refcounted qualifier",
2218 ctype_unparse (ct)),
2219 uentry_whereLast (ue));
2223 else if (qual_isRefs (qel))
2225 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2227 uentry_setAliasKind (ue, AK_REFS);
2232 (FLG_ANNOTATIONERROR,
2233 message ("Refs qualifier used on non-structure field: %q",
2234 uentry_unparse (ue)),
2235 uentry_whereLast (ue));
2238 else if (qual_isAliasQual (qel))
2240 alkind ak = alkind_fromQual (qel);
2242 alkind oldak = uentry_getAliasKind (ue);
2243 ctype ut = uentry_getType (ue);
2245 if (alkind_isImplicit (ak)
2246 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2248 /* ignore the implied qualifier */
2252 if (uentry_isEitherConstant (ue))
2255 (FLG_ANNOTATIONERROR,
2256 message ("Alias qualifier %s used on constant: %q",
2257 alkind_unparse (ak), uentry_unparse (ue)),
2258 uentry_whereLast (ue));
2263 if (ctype_isFunction (ut))
2265 ut = ctype_getReturnType (ut);
2268 if (!(ctype_isVisiblySharable (ut)
2269 || ctype_isRealArray (ut)
2270 || ctype_isRealSU (ut)))
2272 if (!qual_isImplied (qel))
2275 (FLG_ANNOTATIONERROR,
2276 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2277 alkind_unparse (ak), ut, uentry_getName (ue)),
2278 uentry_whereLast (ue));
2285 if (uentry_isRefCounted (ue))
2287 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2288 || qual_isExposed (qel)
2289 || qual_isObserver (qel)))
2291 if (!qual_isImplied (qel))
2294 (FLG_ANNOTATIONERROR,
2296 ("Alias qualifier %s used on reference counted storage: %q",
2297 alkind_unparse (ak),
2298 uentry_unparse (ue)),
2299 uentry_whereLast (ue));
2307 if (qual_isRefQual (qel))
2310 (FLG_ANNOTATIONERROR,
2311 message ("Qualifier %s used on non-reference counted storage: %q",
2312 alkind_unparse (ak), uentry_unparse (ue)),
2313 uentry_whereLast (ue));
2322 uentry_setAliasKind (ue, ak);
2325 else if (qual_isNull (qel))
2327 if (uentry_isConstant (ue))
2331 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2332 uentry_whereDeclared (ue));
2336 uentry_setNullState (ue, NS_POSNULL);
2339 else if (qual_isRelNull (qel))
2341 uentry_setNullState (ue, NS_RELNULL);
2343 else if (qual_isNotNull (qel))
2345 uentry_setNullState (ue, NS_MNOTNULL);
2347 else if (qual_isAbstract (qel)
2348 || qual_isNumAbstract (qel)
2349 || qual_isConcrete (qel))
2351 if (!uentry_isDatatype (ue))
2354 (FLG_ANNOTATIONERROR,
2355 message ("Qualifier %s used with non-datatype",
2356 qual_unparse (qel)),
2357 uentry_whereLast (ue));
2361 ue->info->datatype->abs = qel;
2362 DPRINTF (("Setting abstract %s: %s",
2363 uentry_unparse (ue), qual_unparse (qel)));
2366 else if (qual_isMutable (qel))
2368 if (!uentry_isDatatype (ue))
2371 (FLG_ANNOTATIONERROR,
2372 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2373 uentry_whereLast (ue));
2377 if (!ynm_isOn (ue->info->datatype->mut))
2379 uentry_checkMutableType (ue);
2382 ue->info->datatype->mut = YES;
2385 else if (qual_isImmutable (qel))
2387 if (!uentry_isDatatype (ue))
2389 voptgenerror (FLG_ANNOTATIONERROR,
2390 message ("Qualifier %s used with non-datatype",
2391 qual_unparse (qel)),
2392 uentry_whereLast (ue));
2396 ue->info->datatype->mut = NO;
2399 else if (qual_isNullPred (qel))
2401 uentry_convertVarFunction (ue);
2403 if (uentry_isFunction (ue))
2405 ctype typ = uentry_getType (ue);
2406 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2408 if (ctype_isRealBool (rtype))
2410 uentryList pl = ctype_argsFunction (typ);
2412 if (uentryList_size (pl) == 1)
2414 ue->info->fcn->nullPred = qel;
2418 voptgenerror (FLG_ANNOTATIONERROR,
2419 message ("Qualifier %s used with function having %d "
2420 "arguments (should have 1)",
2422 uentryList_size (pl)),
2423 uentry_whereLast (ue));
2428 voptgenerror (FLG_ANNOTATIONERROR,
2429 message ("Qualifier %s used with function returning %s "
2430 "(should return bool)",
2432 ctype_unparse (rtype)),
2433 uentry_whereLast (ue));
2438 voptgenerror (FLG_ANNOTATIONERROR,
2439 message ("Qualifier %s used with non-function",
2440 qual_unparse (qel)),
2441 uentry_whereLast (ue));
2444 else if (qual_isExitQual (qel))
2446 exitkind exk = exitkind_fromQual (qel);
2448 if (uentry_isFunction (ue))
2450 if (exitkind_isKnown (ue->info->fcn->exitCode))
2452 voptgenerror (FLG_ANNOTATIONERROR,
2453 message ("Multiple exit qualifiers used on function %q: %s, %s",
2454 uentry_getName (ue),
2455 exitkind_unparse (ue->info->fcn->exitCode),
2456 exitkind_unparse (exk)),
2457 uentry_whereLast (ue));
2460 ue->info->fcn->exitCode = exk;
2464 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2466 uentry_makeVarFunction (ue);
2467 ue->info->fcn->exitCode = exk;
2471 voptgenerror (FLG_ANNOTATIONERROR,
2472 message ("Exit qualifier %s used with non-function (type %s)",
2474 ctype_unparse (uentry_getType (ue))),
2475 uentry_whereLast (ue));
2479 else if (qual_isMetaState (qel))
2481 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2483 if (annotationInfo_matchesContext (ainfo, ue))
2485 DPRINTF (("Reflecting %s on %s",
2486 annotationInfo_unparse (ainfo),
2487 uentry_unparseFull (ue)));
2489 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2490 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2491 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2496 (FLG_ANNOTATIONERROR,
2497 message ("Attribute annotation %s used in inconsistent context: %q",
2499 uentry_unparse (ue)),
2500 uentry_whereLast (ue)))
2502 /* annotationInfo_showContextError (ainfo, ue); */
2508 if (qual_isCQual (qel))
2514 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2520 uentry_reflectQualifiers (uentry ue, qualList q)
2522 llassert (uentry_isValid (ue));
2524 DPRINTF (("Reflect qualifiers: %s / %s",
2525 uentry_unparseFull (ue), qualList_unparse (q)));
2527 qualList_elements (q, qel)
2529 if (qual_isStatic (qel))
2531 uentry_setStatic (ue);
2533 else if (qual_isUnused (qel))
2535 uentry_setUsed (ue, fileloc_undefined);
2536 DPRINTF (("Used: %s", uentry_unparseFull (ue)));
2538 else if (qual_isExternal (qel))
2540 fileloc_free (ue->whereDefined);
2541 ue->whereDefined = fileloc_createExternal ();
2543 else if (qual_isSef (qel))
2545 if (uentry_isVariable (ue))
2547 vkind vk = ue->info->var->kind;
2549 llassert (vk != VKREFPARAM);
2551 if (vk == VKYIELDPARAM)
2554 (FLG_ANNOTATIONERROR,
2555 message ("Qualifier sef cannot be used with %s: %q",
2556 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2557 uentry_unparse (ue)),
2558 uentry_whereLast (ue));
2560 else if (vk == VKRETPARAM)
2562 ue->info->var->kind = VKSEFRETPARAM;
2566 ue->info->var->kind = VKSEFPARAM;
2572 (FLG_ANNOTATIONERROR,
2573 message ("Qualifier sef is meaningful only on parameters: %q",
2574 uentry_unparse (ue)),
2575 uentry_whereLast (ue));
2578 else if (qual_isExtern (qel))
2580 ue->storageclass = SCEXTERN;
2582 else if (qual_isGlobalQual (qel)) /* undef, killed */
2584 DPRINTF (("Reflecting qual: %s / %s",
2585 qual_unparse (qel), uentry_unparse (ue)));
2587 if (uentry_isVariable (ue))
2589 sstate oldstate = ue->info->var->defstate;
2590 sstate defstate = sstate_fromQual (qel);
2593 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2594 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2596 defstate = SS_UNDEFKILLED;
2603 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2604 ue->info->var->defstate = defstate;
2609 (FLG_ANNOTATIONERROR,
2610 message ("Qualifier %s used on non-variable: %q",
2611 qual_unparse (qel), uentry_unparse (ue)),
2612 uentry_whereLast (ue));
2615 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2617 /* start modifications */
2618 else if( qual_isBufQualifier(qel) ) {
2619 ctype ct = ctype_realType(uentry_getType(ue));
2620 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2622 if( uentry_hasBufStateInfo(ue) ) {
2623 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2625 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2626 /* If formal func param */
2627 uentry_setNullTerminatedState(ue);
2628 uentry_setLen (ue, 1);
2629 uentry_setSize (ue, 1);
2631 sRef_setNullTerminatedState(uentry_getSref(ue));
2632 sRef_setLen (uentry_getSref(ue), 1);
2633 sRef_setSize (uentry_getSref(ue), 1);
2635 uentry_setPossiblyNullTerminatedState(ue);
2637 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2641 /* put other BufState Qualifiers here */
2643 cstring s = uentry_getName(ue);
2644 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2645 struct for identifier %s\n", s) );
2647 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2649 sRef retSref = uentry_getSref (ue);
2650 ctype retType = sRef_getType (retSref);
2652 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2653 sRef_setNullTerminatedState (retSref);
2659 message ("Qualifier %s used on non-pointer on \
2660 function return: %q", qual_unparse (qel),
2661 uentry_unparse (ue)));
2668 message ("Qualifier %s used on non-pointer: %q",
2669 qual_unparse (qel), uentry_unparse (ue)));
2671 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2673 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2675 ctype realType = ctype_realType (ue->utype);
2676 sstate defstate = sstate_fromQual (qel);
2678 if (ctype_isFunction (realType))
2680 realType = ctype_realType (ctype_getReturnType (realType));
2683 if (qual_isRelDef (qel))
2685 ; /* okay anywhere */
2689 if (!ctype_isAP (realType)
2690 && !ctype_isSU (realType)
2691 && !ctype_isUnknown (realType)
2692 && !ctype_isAbstract (ue->utype))
2695 (FLG_ANNOTATIONERROR,
2696 message ("Qualifier %s used on non-pointer or struct: %q",
2697 qual_unparse (qel), uentry_unparse (ue)),
2698 uentry_whereLast (ue));
2702 uentry_setDefState (ue, defstate);
2704 if (sRef_isStateSpecial (ue->sref)
2705 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2707 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2710 else if (qual_isYield (qel))
2712 if (uentry_isVariable (ue))
2714 ue->info->var->kind = VKYIELDPARAM;
2719 (FLG_ANNOTATIONERROR,
2720 message ("Qualifier %s used on non-iterator parameter: %q",
2721 qual_unparse (qel), uentry_unparse (ue)),
2722 uentry_whereLast (ue));
2725 else if (qual_isExQual (qel))
2727 exkind ek = exkind_fromQual (qel);
2728 ctype ut = uentry_getType (ue);
2730 DPRINTF (("Reflect ex qual: %s / %s",
2731 uentry_unparse (ue), exkind_unparse (ek)));
2733 if (ctype_isFunction (ut))
2735 ut = ctype_getReturnType (ut);
2738 if (!(ctype_isVisiblySharable (ut))
2739 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2740 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2742 if (!qual_isImplied (qel))
2744 if (ctype_isImmutableAbstract (ut)) {
2746 (FLG_REDUNDANTSHAREQUAL,
2747 message ("Qualifier %s used on unsharable storage type %t: %q",
2748 exkind_unparse (ek), ut, uentry_getName (ue)),
2749 uentry_whereLast (ue));
2752 (FLG_MISPLACEDSHAREQUAL,
2753 message ("Qualifier %s used on unsharable storage type %t: %q",
2754 exkind_unparse (ek), ut, uentry_getName (ue)),
2755 uentry_whereLast (ue));
2761 alkind ak = sRef_getAliasKind (ue->sref);
2763 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2764 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2766 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2768 if (!alkind_isTemp (ak))
2770 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2771 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2774 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2775 || alkind_isOwned (ak))
2783 message ("Exposure qualifier %s used on %s storage (should "
2784 "be dependent): %q",
2786 alkind_unparse (ak),
2787 uentry_unparse (ue)));
2791 else if (qual_isGlobCheck (qel))
2793 if (uentry_isVariable (ue))
2795 chkind ch = chkind_fromQual (qel);
2797 if (ue->info->var->checked != CH_UNKNOWN)
2799 if (ch == ue->info->var->checked)
2801 llerror (FLG_SYNTAX,
2802 message ("Redundant %s qualifier on %q",
2804 uentry_getName (ue)));
2808 llerror (FLG_SYNTAX,
2810 ("Contradictory %s and %s qualifiers on %q",
2812 checkedName (ue->info->var->checked),
2813 uentry_getName (ue)));
2817 ue->info->var->checked = ch;
2823 message ("Qualifier %s used with non-variable",
2824 qual_unparse (qel)));
2827 else if (qual_isReturned (qel))
2829 if (uentry_isVariable (ue))
2831 ue->info->var->kind = VKRETPARAM;
2835 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2836 qual_unparse (qel)));
2841 uentry_reflectOtherQualifier (ue, qel);
2844 sRef_storeState (ue->sref);
2845 } end_qualList_elements;
2849 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2853 uentry_isOnly (uentry ue)
2855 return (!uentry_isUndefined (ue)
2856 && uentry_isVariable (ue)
2857 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2861 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2863 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2864 sRef_setOrigAliasKind (ue->sref, ak);
2868 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2870 if (uentry_isVariable (ue))
2872 ue->info->var->nullstate = ns;
2875 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2879 uentry_isUnique (uentry ue)
2881 return (!uentry_isUndefined (ue)
2882 && uentry_isVariable (ue)
2883 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2887 uentry_isFileStatic (uentry ue)
2889 return (uentry_isStatic (ue)
2890 && (!uentry_isVariable (ue)
2891 || sRef_isFileStatic (uentry_getSref (ue))));
2895 uentry_isExported (uentry ue)
2897 if (uentry_isValid (ue))
2899 if (uentry_isVariable (ue))
2901 return (sRef_isRealGlobal (uentry_getSref (ue)));
2905 return !uentry_isStatic (ue);
2913 uentry_isNonLocal (uentry ue)
2915 return (uentry_isValid (ue) && uentry_isVariable (ue)
2916 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2920 uentry_isGlobalVariable (uentry ue)
2922 return (uentry_isValid (ue) && uentry_isVariable (ue)
2923 && sRef_isFileOrGlobalScope (ue->sref));
2927 uentry_isVisibleExternally (uentry ue)
2929 return (uentry_isValid (ue)
2930 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2931 || (!uentry_isStatic (ue)
2932 && (uentry_isFunction (ue)
2933 || uentry_isIter (ue)
2934 || uentry_isEndIter (ue)
2935 || uentry_isConstant (ue)
2936 || uentry_isDatatype (ue)
2937 || uentry_isAnyTag (ue)))));
2941 uentry_isPrintfLike (uentry ue)
2943 return (uentry_isFunction (ue)
2944 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2948 uentry_isScanfLike (uentry ue)
2950 return (uentry_isFunction (ue)
2951 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2955 uentry_isMessageLike (uentry ue)
2957 return (uentry_isFunction (ue)
2958 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2961 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2963 uentryList args = uentry_getParams (ue);
2965 if (!uentryList_isMissingParams (args))
2967 uentry last = uentry_undefined;
2969 uentryList_elements (args, current)
2971 if (uentry_isElipsisMarker (current))
2973 if (uentry_isUndefined (last))
2977 message ("Function %q is marked %s, but has no format "
2978 "string argument before elipsis",
2979 uentry_getName (ue),
2980 specCode_unparse (ue->info->fcn->specialCode)),
2981 uentry_whereLast (ue));
2982 ue->info->fcn->specialCode = SPC_NONE;
2986 ctype rt = ctype_realType (uentry_getType (last));
2988 if (!ctype_match (rt, ctype_string))
2992 /* wchar_t * is okay too */
2993 if (ctype_isAP (rt))
2995 ctype base = ctype_baseArrayPtr (rt);
2997 if (ctype_isArbitraryIntegral (base))
3007 message ("Function %q is marked %s, but the argument "
3008 "before the elipsis has type %s (should be char *)",
3009 uentry_getName (ue),
3010 specCode_unparse (ue->info->fcn->specialCode),
3011 ctype_unparse (uentry_getType (last))),
3012 uentry_whereLast (ue));
3014 ue->info->fcn->specialCode = SPC_NONE;
3021 } end_uentryList_elements ;
3025 message ("Function %q is marked %s, but has no elipsis parameter",
3026 uentry_getName (ue),
3027 specCode_unparse (ue->info->fcn->specialCode)),
3028 uentry_whereLast (ue));
3030 ue->info->fcn->specialCode = SPC_NONE;
3035 uentry_setPrintfLike (uentry ue)
3037 uentry_convertVarFunction (ue);
3038 llassertfatal (uentry_isFunction (ue));
3039 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3040 checkSpecialFunction (ue);
3044 uentry_setScanfLike (uentry ue)
3046 uentry_convertVarFunction (ue);
3047 llassertfatal (uentry_isFunction (ue));
3048 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3049 checkSpecialFunction (ue);
3053 uentry_setMessageLike (uentry ue)
3055 uentry_convertVarFunction (ue);
3056 llassertfatal (uentry_isFunction (ue));
3057 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3058 checkSpecialFunction (ue);
3062 uentry_isSpecialFunction (uentry ue)
3064 return (uentry_isFunction (ue)
3065 && (ue->info->fcn->specialCode != SPC_NONE));
3068 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3070 ctype ct = idDecl_getCtype (t);
3072 fileloc loc = setLocation ();
3073 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc, SA_CREATED));
3074 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3076 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3077 DPRINTF (("Base: %s [%d]", ctype_unparse (base), ctype_isFixedArray (base)));
3078 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3079 uentry_implicitParamAnnots (ue);
3081 /* Parameter type [][] or [x][] is invalid, but [][x] is okay */
3083 while (ctype_isFixedArray (base))
3085 base = ctype_baseArrayPtr (base);
3088 DPRINTF (("Base: %s", ctype_unparse (base)));
3090 if (ctype_isIncompleteArray (base))
3092 base = ctype_baseArrayPtr (base);
3093 DPRINTF (("Base: %s", ctype_unparse (base)));
3094 if (ctype_isArray (base))
3096 if (!uentry_hasName (ue))
3099 (FLG_INCOMPLETETYPE,
3100 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3102 ctype_unparse (ct)),
3103 uentry_whereLast (ue));
3108 (FLG_INCOMPLETETYPE,
3109 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3110 uentry_getName (ue),
3111 ctype_unparse (ct)),
3112 uentry_whereLast (ue));
3117 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3121 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3123 ctype ct = idDecl_getCtype (t);
3125 if (ctype_isFunction (ct))
3127 return (uentry_makeIdFunction (t));
3131 fileloc loc = setLocation ();
3132 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3134 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3136 if (!uentry_isExtern (ue))
3138 uentry_setDefined (ue, loc);
3145 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3147 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3154 static /*@only@*/ /*@notnull@*/
3155 uentry uentry_makeConstantAux (cstring n, ctype t,
3156 /*@keep@*/ fileloc f, bool priv, bool macro,
3157 /*@only@*/ multiVal m)
3159 uentry e = uentry_alloc ();
3162 e->uname = cstring_copy (n);
3164 e->storageclass = SCNONE;
3166 e->warn = warnClause_undefined; /* Don't support warnings for constants */
3168 e->sref = sRef_makeConst (t);
3173 e->uses = filelocList_new ();
3174 e->isPrivate = priv;
3175 e->hasNameError = FALSE;
3177 e->info = (uinfo) dmalloc (sizeof (*e->info));
3178 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3179 e->info->uconst->access = typeIdSet_undefined;
3180 e->info->uconst->macro = macro;
3182 uentry_setSpecDef (e, f);
3184 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3186 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3189 uentry_setConstantValue (e, m);
3194 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3196 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
3200 /*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
3202 uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
3206 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3208 uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
3212 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3214 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3215 idDecl_getCtype (t),
3218 llassert (fileloc_isUndefined (ue->whereDeclared));
3219 ue->whereDeclared = setLocation ();
3220 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3222 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3223 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3231 void uentry_setDefState (uentry ue, sstate defstate)
3233 if (uentry_isValid (ue))
3235 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3237 if (uentry_isVariable (ue))
3239 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3244 bool uentry_isCheckedUnknown (uentry ue)
3246 return (uentry_isVar (ue)
3247 && (ue->info->var->checked == CH_UNKNOWN));
3250 bool uentry_isCheckMod (uentry ue)
3252 return (uentry_isVar (ue)
3253 && (ue->info->var->checked == CH_CHECKMOD));
3256 bool uentry_isUnchecked (uentry ue)
3258 return (uentry_isVar (ue)
3259 && (ue->info->var->checked == CH_UNCHECKED));
3262 bool uentry_isChecked (uentry ue)
3264 return (uentry_isVar (ue)
3265 && (ue->info->var->checked == CH_CHECKED));
3268 bool uentry_isCheckedModify (uentry ue)
3270 return (uentry_isVar (ue)
3271 && (ue->info->var->checked == CH_CHECKED
3272 || ue->info->var->checked == CH_CHECKMOD
3273 || ue->info->var->checked == CH_CHECKEDSTRICT));
3276 bool uentry_isCheckedStrict (uentry ue)
3278 return (uentry_isVar (ue)
3279 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3282 void uentry_setUnchecked (uentry ue)
3284 llassert (uentry_isVar (ue));
3286 ue->info->var->checked = CH_UNCHECKED;
3289 void uentry_setChecked (uentry ue)
3291 llassert (uentry_isVar (ue));
3293 ue->info->var->checked = CH_CHECKED;
3296 void uentry_setCheckMod (uentry ue)
3298 llassert (uentry_isVar (ue));
3300 ue->info->var->checked = CH_CHECKMOD;
3303 void uentry_setCheckedStrict (uentry ue)
3305 llassert (uentry_isVar (ue));
3307 ue->info->var->checked = CH_CHECKEDSTRICT;
3310 static /*@only@*/ /*@notnull@*/
3311 uentry uentry_makeVariableAux (cstring n, ctype t,
3313 /*@exposed@*/ sRef s,
3314 bool priv, vkind kind)
3316 uentry e = uentry_alloc ();
3319 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3322 e->uname = cstring_copy (n);
3325 e->storageclass = SCNONE;
3327 e->warn = warnClause_undefined; /* Don't support warnings for variables yet @*/
3334 e->uses = filelocList_new ();
3335 e->isPrivate = priv;
3336 e->hasNameError = FALSE;
3338 e->info = (uinfo) dmalloc (sizeof (*e->info));
3339 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3340 e->info->var->kind = kind;
3342 /* removed: e->info->var->origsref = sRef_saveCopy (e->sref); */
3343 e->info->var->checked = CH_UNKNOWN;
3345 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3346 uentry_setSpecDef (e, f);
3347 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3349 if (ctype_isFunction (rt))
3351 rt = ctype_getReturnType (rt);
3354 if (ctype_isUA (rt))
3356 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3357 sRef_setStateFromType (e->sref, rt);
3360 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3361 e->info->var->defstate = sRef_getDefState (e->sref);
3362 e->info->var->nullstate = sRef_getNullState (e->sref);
3364 /* start modifications */
3365 /* This function sets the uentry for a pointer or array variable declaration,
3366 it allocates memory and sets the fields. We check if the type of the variable
3367 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3369 if (ctype_isArray (t) || ctype_isPointer(t))
3371 e->info->var->bufinfo = dmalloc (sizeof (*e->info->var->bufinfo));
3372 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3373 sRef_setNotNullTerminatedState (s);
3377 e->info->var->bufinfo = NULL;
3379 /* end modification */
3385 uentry_isYield (uentry ue)
3387 return (uentry_isVariable (ue)
3388 && (ue->info->var->kind == VKYIELDPARAM
3389 || ue->info->var->kind == VKREFYIELDPARAM));
3393 uentry_isRefsField (uentry ue)
3395 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3398 /*@only@*/ /*@notnull@*/
3399 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3401 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3402 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3409 void uentry_makeVarFunction (uentry ue)
3416 llassert (uentry_isValid (ue));
3417 llassert (!sRef_modInFunction ());
3419 ak = sRef_getOrigAliasKind (ue->sref);
3420 ek = sRef_getOrigExKind (ue->sref);
3422 llassert (uentry_isVariable (ue));
3423 oldInfo = ue->info->var;
3425 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3426 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
3429 ** expanded macro is marked used
3432 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3435 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3436 ue->info->fcn->exitCode = XK_UNKNOWN;
3437 ue->info->fcn->nullPred = qual_createUnknown ();
3438 ue->info->fcn->specialCode = SPC_NONE;
3439 ue->info->fcn->access = typeIdSet_undefined;
3440 ue->info->fcn->hasGlobs = FALSE;
3441 ue->info->fcn->globs = globSet_undefined;
3442 ue->info->fcn->hasMods = FALSE;
3443 ue->info->fcn->mods = sRefSet_undefined;
3444 ue->info->fcn->specclauses = NULL;
3445 ue->info->fcn->defparams = uentryList_undefined;
3448 ue->info->fcn->preconditions = functionConstraint_undefined;
3452 ue->info->fcn->postconditions = functionConstraint_undefined;
3455 if (ctype_isFunction (ue->utype))
3457 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3461 ue->sref = sRef_makeType (ctype_unknown);
3464 if (sRef_isRefCounted (ue->sref))
3470 if (alkind_isUnknown (ak))
3472 if (exkind_isKnown (ek))
3474 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3475 ak = AK_IMPDEPENDENT;
3479 if (context_getFlag (FLG_RETIMPONLY))
3481 if (ctype_isFunction (ue->utype)
3482 && ctype_isVisiblySharable
3483 (ctype_realType (ctype_getReturnType (ue->utype))))
3485 if (uentryList_hasReturned (uentry_getParams (ue)))
3491 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3506 loc = ue->whereDeclared;
3508 sRef_setAliasKind (ue->sref, ak, loc);
3509 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3510 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3511 sRef_setExKind (ue->sref, ek, loc);
3513 if (oldInfo->kind == VKEXPMACRO)
3519 fileloc_free (ue->whereDefined);
3520 ue->whereDefined = fileloc_undefined;
3523 uvinfo_free (oldInfo);
3526 void uentry_makeConstantFunction (uentry ue)
3533 llassert (uentry_isValid (ue));
3534 llassert (!sRef_modInFunction ());
3536 ak = sRef_getOrigAliasKind (ue->sref);
3537 ek = sRef_getOrigExKind (ue->sref);
3539 llassert (uentry_isConstant (ue));
3540 oldInfo = ue->info->uconst;
3542 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3545 ** expanded macro is marked used (until I write a pre-processor)
3549 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3550 ue->info->fcn->exitCode = XK_UNKNOWN;
3551 ue->info->fcn->nullPred = qual_createUnknown ();
3552 ue->info->fcn->specialCode = SPC_NONE;
3553 ue->info->fcn->access = typeIdSet_undefined;
3554 ue->info->fcn->hasGlobs = FALSE;
3555 ue->info->fcn->globs = globSet_undefined;
3556 ue->info->fcn->hasMods = FALSE;
3557 ue->info->fcn->mods = sRefSet_undefined;
3558 ue->info->fcn->specclauses = NULL;
3559 ue->info->fcn->defparams = uentryList_undefined;
3562 ue->info->fcn->preconditions = functionConstraint_undefined;
3566 ue->info->fcn->postconditions = functionConstraint_undefined;
3570 if (ctype_isFunction (ue->utype))
3572 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3576 ue->sref = sRef_makeType (ctype_unknown);
3579 if (sRef_isRefCounted (ue->sref))
3585 if (alkind_isUnknown (ak))
3587 if (exkind_isKnown (ek))
3589 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3590 ak = AK_IMPDEPENDENT;
3594 if (context_getFlag (FLG_RETIMPONLY))
3596 if (ctype_isFunction (ue->utype)
3597 && ctype_isVisiblySharable
3598 (ctype_realType (ctype_getReturnType (ue->utype))))
3600 if (uentryList_hasReturned (uentry_getParams (ue)))
3606 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3621 loc = ue->whereDeclared;
3623 sRef_setAliasKind (ue->sref, ak, loc);
3624 sRef_setExKind (ue->sref, ek, loc);
3626 fileloc_free (ue->whereDefined);
3627 ue->whereDefined = fileloc_undefined;
3628 ucinfo_free (oldInfo);
3632 uentry_setGlobals (uentry ue, /*@only@*/ globSet globs)
3634 llassert (uentry_isValid (ue));
3636 globSet_markImmutable (globs);
3638 if (uentry_isIter (ue))
3640 ue->info->iter->globs = globSet_unionFree (ue->info->iter->globs, globs);
3644 uentry_convertVarFunction (ue);
3645 llassert (uentry_isFunction (ue));
3647 ue->info->fcn->hasGlobs = TRUE;
3648 ue->info->fcn->globs = globSet_unionFree (ue->info->fcn->globs, globs);
3651 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3653 ue->info->fcn->hasMods = TRUE;
3657 void uentry_addAccessType (uentry ue, typeId tid)
3659 if (uentry_isFunction (ue))
3661 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3663 else if (uentry_isEitherConstant (ue))
3665 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3667 else if (uentry_isIter (ue))
3669 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3671 else if (uentry_isEndIter (ue))
3673 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3677 llbug (message ("no access for: %q", uentry_unparse (ue)));
3681 /*@only@*/ /*@notnull@*/ uentry
3682 uentry_makeFunction (cstring n, ctype t,
3684 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3685 /*@only@*/ warnClause warn,
3688 llassert (warnClause_isUndefined (warn));
3689 return (uentry_makeFunctionAux (n, t,
3690 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3691 : typeIdSet_single (access)),
3697 /*@notnull@*/ uentry
3698 uentry_makePrivFunction2 (cstring n, ctype t,
3700 globSet globs, sRefSet mods,
3703 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3708 /*@notnull@*/ uentry
3709 uentry_makeSpecFunction (cstring n, ctype t,
3711 /*@only@*/ globSet globs,
3712 /*@only@*/ sRefSet mods,
3715 uentry ue = uentry_makeFunctionAux (n, t, access,
3716 globs, mods, warnClause_undefined,
3719 uentry_setHasGlobs (ue);
3720 uentry_setHasMods (ue);
3722 reflectImplicitFunctionQualifiers (ue, TRUE);
3726 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3728 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3729 sRef_undefined, FALSE, VKEXPMACRO);
3731 uentry_setDefined (ue, f);
3735 /*@notnull@*/ /*@notnull@*/ uentry
3736 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3738 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3739 typeIdSet_singleOpt (access),
3740 globSet_undefined, sRefSet_undefined,
3741 warnClause_undefined,
3745 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3749 bool uentry_isForward (uentry e)
3751 if (uentry_isValid (e))
3753 ctype ct = uentry_getType (e);
3755 return (ctype_isUnknown (ct)
3756 || (ctype_isFunction (ct)
3757 && ctype_isUnknown (ctype_getReturnType (ct))));
3763 /*@notnull@*/ uentry
3764 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3766 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3767 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3771 /*@notnull@*/ uentry
3772 uentry_makeUnspecFunction (cstring n, ctype t,
3776 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3777 sRefSet_undefined, warnClause_undefined,
3780 reflectImplicitFunctionQualifiers (ue, TRUE);
3788 /* is exported for use by usymtab_interface */
3790 /*@notnull@*/ uentry
3791 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, qual abstract,
3792 fileloc f, bool priv)
3794 uentry e = uentry_alloc ();
3796 DPRINTF (("Make datatype: %s / %s",
3797 n, ctype_unparse (t)));
3799 /* e->shallowCopy = FALSE; */
3800 e->ukind = KDATATYPE;
3801 e->uname = cstring_copy (n);
3803 e->storageclass = SCNONE;
3804 e->sref = sRef_makeUnknown ();
3808 sRef_setStateFromType (e->sref, t);
3811 uentry_setSpecDef (e, f);
3813 e->warn = warnClause_undefined;
3814 e->uses = filelocList_new ();
3815 e->isPrivate = priv;
3816 e->hasNameError = FALSE;
3821 e->info = (uinfo) dmalloc (sizeof (*e->info));
3822 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3823 e->info->datatype->abs = abstract;
3824 e->info->datatype->mut = mut;
3825 e->info->datatype->type = ctype_undefined;
3827 if (uentry_isDeclared (e))
3829 uentry_setDefined (e, f);
3832 if (qual_isAbstract (abstract) && !(uentry_isCodeDefined (e)))
3834 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3840 /*@notnull@*/ uentry
3841 uentry_makeDatatype (cstring n, ctype t, ynm mut, qual abstract, fileloc f)
3843 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3846 /*@notnull@*/ uentry uentry_makeBoolDatatype (qual abstract)
3848 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3849 ctype_bool, NO, abstract,
3850 fileloc_getBuiltin (),
3853 ret->info->datatype->type = ctype_bool;
3861 static /*@only@*/ /*@notnull@*/ uentry
3862 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3863 /*@only@*/ fileloc f)
3865 uentry e = uentry_alloc ();
3868 e->uname = cstring_copy (n);
3870 e->sref = sRef_makeUnknown ();
3871 e->storageclass = SCNONE;
3875 uentry_setSpecDef (e, f);
3877 e->warn = warnClause_undefined;
3878 e->uses = filelocList_new ();
3879 e->isPrivate = FALSE;
3880 e->hasNameError = FALSE;
3882 e->info = (uinfo) dmalloc (sizeof (*e->info));
3883 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3884 e->info->iter->access = access;
3885 e->info->iter->mods = sRefSet_undefined;
3886 e->info->iter->globs = globSet_undefined;
3888 uentry_checkIterArgs (e);
3892 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3894 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3897 static /*@notnull@*/ uentry
3898 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3900 uentry e = uentry_alloc ();
3902 /* e->shallowCopy = FALSE; */
3903 e->ukind = KENDITER;
3904 e->storageclass = SCNONE;
3905 e->uname = message ("end_%s", n);
3906 e->utype = ctype_unknown;
3907 e->sref = sRef_makeUnknown ();
3909 uentry_setSpecDef (e, f);
3914 e->uses = filelocList_new ();
3915 e->isPrivate = FALSE;
3916 e->hasNameError = FALSE;
3918 e->info = (uinfo) dmalloc (sizeof (*e->info));
3919 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3921 e->info->enditer->access = access;
3922 e->warn = warnClause_undefined;
3927 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3929 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3936 static /*@only@*/ /*@notnull@*/ uentry
3937 uentry_makeTagAux (cstring n, ctype t,
3938 /*@only@*/ fileloc fl,
3939 bool priv, ekind kind)
3941 uentry e = uentry_alloc ();
3943 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3945 llbuglit ("uentry_makeTagAux: not a tag type");
3949 /* e->shallowCopy = FALSE; */
3950 e->uname = cstring_copy (n);
3953 e->sref = sRef_makeUnknown ();
3954 e->storageclass = SCNONE;
3956 uentry_setSpecDef (e, fl);
3961 e->uses = filelocList_new ();
3962 e->isPrivate = priv;
3963 e->hasNameError = FALSE;
3965 e->info = (uinfo) dmalloc (sizeof (*e->info));
3966 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3967 e->info->datatype->abs = qual_createUnknown ();
3968 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3969 e->info->datatype->type = t;
3970 e->warn = warnClause_undefined;
3972 if (uentry_isDeclared (e))
3974 uentry_setDefined (e, fl);
3980 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3982 cstring sname = makeStruct (n);
3983 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3985 cstring_free (sname);
3990 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3992 cstring sname = makeStruct (n);
3993 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3995 cstring_free (sname);
4000 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
4002 cstring uname = makeUnion (n);
4003 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
4005 cstring_free (uname);
4010 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
4012 cstring ename = makeEnum (n);
4013 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
4015 cstring_free (ename);
4020 uentry_makeUnionTagLoc (cstring n, ctype t)
4022 cstring uname = makeUnion (n);
4023 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
4025 cstring_free (uname);
4030 uentry_makeEnumTagLoc (cstring n, ctype t)
4032 cstring ename = makeEnum (n);
4033 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4035 cstring_free (ename);
4040 uentry_isStructTag (uentry ue)
4042 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4046 uentry_isUnionTag (uentry ue)
4048 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4052 uentry_isEnumTag (uentry ue)
4054 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4058 uentry_isAnyTag (uentry ue)
4060 return (uentry_isStructTag (ue)
4061 || uentry_isUnionTag (ue)
4062 || uentry_isEnumTag (ue));
4065 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4067 extern void uentry_destroyMod (void)
4068 /*@globals killed emarker@*/ /*@modifies emarker@*/
4070 static bool wasDestroyed = FALSE;
4072 llassert (!wasDestroyed);
4074 if (emarker != NULL)
4076 uentry_reallyFree (emarker);
4079 wasDestroyed = TRUE;
4083 uentry_makeElipsisMarker (void)
4085 if (emarker == NULL)
4087 emarker = uentry_alloc ();
4089 emarker->ukind = KELIPSMARKER;
4090 emarker->uname = cstring_makeLiteral ("...");
4091 emarker->utype = ctype_elipsMarker;
4092 emarker->sref = sRef_undefined;
4093 emarker->storageclass = SCNONE;
4094 emarker->used = FALSE;
4095 emarker->lset = FALSE;
4096 emarker->info = NULL;
4098 uentry_setSpecDef (emarker, fileloc_undefined);
4099 emarker->uses = filelocList_new ();
4100 emarker->isPrivate = FALSE;
4101 emarker->hasNameError = FALSE;
4104 /*@ignore@*/ return (emarker); /*@end@*/
4112 uentry_equiv (uentry p1, uentry p2)
4114 if (uentry_compare (p1, p2) != 0)
4125 uentry_xcomparealpha (uentry *p1, uentry *p2)
4129 if ((res = uentry_compare (*p1, *p2)) == 0) {
4130 if ((*p1 != NULL) && (*p2 != NULL)) {
4131 res = cstring_compare ((*p1)->uname,
4140 uentry_xcompareuses (uentry *p1, uentry *p2)
4145 if (uentry_isValid (u1))
4147 if (uentry_isValid (u2))
4149 return (-1 * int_compare (filelocList_size (u1->uses),
4150 filelocList_size (u2->uses)));
4159 if (uentry_isValid (u2))
4171 uentry_compareStrict (uentry v1, uentry v2)
4173 COMPARERETURN (uentry_compare (v1, v2));
4175 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4177 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4178 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4179 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4186 uentry_compare (uentry u1, uentry u2)
4188 if (u1 == u2) return 0;
4190 if (uentry_isInvalid (u1)) return -1;
4191 if (uentry_isInvalid (u2)) return 1;
4193 INTCOMPARERETURN (u1->ukind, u2->ukind);
4194 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4195 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4196 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4202 /* bug detected by splint:
4203 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4208 return (multiVal_compare (uentry_getConstantValue (u1),
4209 uentry_getConstantValue (u2)));
4213 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4215 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4216 uentry_accessType (u2)));
4217 return (uentryList_compareParams (uentry_getParams (u1),
4218 uentry_getParams (u2)));
4220 return (typeIdSet_compare (uentry_accessType (u1),
4221 uentry_accessType (u2)));
4224 ** Functions are never equivalent
4227 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4237 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4238 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4239 sRef_getOrigAliasKind (u2->sref)));
4240 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4241 sRef_getOrigExKind (u2->sref)));
4242 COMPARERETURN (generic_compare (u1->info->var->checked,
4243 u2->info->var->checked));
4244 COMPARERETURN (generic_compare (u1->info->var->defstate,
4245 u2->info->var->defstate));
4246 return (generic_compare (u1->info->var->nullstate,
4247 u2->info->var->nullstate));
4249 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4250 u2->info->datatype->type));
4251 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4252 u2->info->datatype->mut));
4253 return (generic_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4262 ** all entries are: <type>[@<info>]*#<name>
4264 ** info depends on kind:
4268 advanceField (char **s)
4270 reader_checkChar (s, '@');
4274 advanceName (char **s)
4276 reader_checkChar (s, '#');
4280 vkind_fromInt (int i)
4282 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4284 llbuglit ("vkind_fromInt: out of range");
4291 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4292 typeIdSet access, nstate nullstate,
4293 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4295 uentry e = uentry_alloc ();
4300 e->sref = sRef_makeConst (ct);
4302 sRef_setNullState (e->sref, nullstate, loc);
4303 e->storageclass = SCNONE;
4305 if (fileloc_isSpec (loc))
4307 e->whereSpecified = loc;
4308 e->whereDeclared = fileloc_undefined;
4312 e->whereSpecified = fileloc_undefined;
4313 e->whereDeclared = loc;
4316 e->whereDefined = fileloc_undefined;
4317 e->uses = filelocList_new ();
4318 e->isPrivate = FALSE;
4319 e->hasNameError = FALSE;
4324 e->warn = warnClause_undefined;
4326 e->info = (uinfo) dmalloc (sizeof (*e->info));
4327 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4328 e->info->uconst->access = access;
4329 e->info->uconst->macro = FALSE; /* fix this when macro info added to library */
4330 uentry_setConstantValue (e, m);
4331 sRef_storeState (e->sref);
4336 static /*@only@*/ uentry
4337 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4338 sstate defstate, nstate isnull, alkind aliased,
4339 exkind exp, chkind checked,
4340 /*@only@*/ fileloc loc)
4342 uentry e = uentry_alloc ();
4347 e->storageclass = SCNONE;
4349 e->sref = sRef_makeType (ct);
4350 sRef_setNullState (e->sref, isnull, loc);
4352 e->whereDefined = fileloc_undefined;
4354 if (fileloc_isSpec (loc))
4356 e->whereSpecified = loc;
4357 e->whereDeclared = fileloc_undefined;
4361 e->whereSpecified = fileloc_undefined;
4362 e->whereDeclared = loc;
4365 e->isPrivate = FALSE;
4366 e->hasNameError = FALSE;
4371 e->uses = filelocList_new ();
4372 e->warn = warnClause_undefined;
4374 e->info = (uinfo) dmalloc (sizeof (*e->info));
4375 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4376 e->info->var->kind = kind;
4377 e->info->var->checked = checked;
4378 e->info->var->defstate = defstate;
4380 sRef_setDefState (e->sref, defstate, loc);
4382 e->info->var->nullstate = sRef_getNullState (e->sref);
4384 sRef_setExKind (e->sref, exp, loc);
4385 sRef_setAliasKind (e->sref, aliased, loc);
4387 sRef_storeState (e->sref);
4389 /*DRL ADDED 9-1-2000 */
4390 e->info->var->bufinfo = NULL;
4395 static /*@only@*/ uentry
4396 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, qual abstract,
4397 ynm mut, ctype rtype, alkind ak, exkind exp,
4398 sstate defstate, nstate isnull,
4399 /*@only@*/ fileloc loc)
4401 uentry e = uentry_alloc ();
4403 e->ukind = KDATATYPE;
4404 /* e->shallowCopy = FALSE; */
4407 e->storageclass = SCNONE;
4408 e->sref = sRef_makeUnknown ();
4409 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4412 ** This is only setting null state. (I think?)
4415 if (ctype_isUA (ct))
4417 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4419 if (uentry_isValid (te))
4421 sRef_setStateFromUentry (e->sref, te);
4425 /* problem for recursive type definitions */
4429 sRef_setAliasKind (e->sref, ak, loc);
4430 sRef_setExKind (e->sref, exp, loc);
4432 sRef_setDefState (e->sref, defstate, loc);
4434 if (qual_isEitherAbstract (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4436 isnull = NS_ABSNULL;
4439 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4440 sRef_mergeNullState (e->sref, isnull);
4442 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4444 if (fileloc_isSpec (loc))
4446 e->whereSpecified = loc;
4447 e->whereDeclared = fileloc_undefined;
4451 e->whereSpecified = fileloc_undefined;
4452 e->whereDeclared = loc;
4455 e->isPrivate = FALSE;
4456 e->hasNameError = FALSE;
4457 e->warn = warnClause_undefined;
4460 e->uses = filelocList_new ();
4462 e->info = (uinfo) dmalloc (sizeof (*e->info));
4463 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4464 e->info->datatype->abs = abstract;
4465 e->info->datatype->mut = mut;
4466 e->info->datatype->type = rtype;
4468 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4469 sRef_storeState (e->sref);
4470 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4475 static void uentry_setHasGlobs (uentry ue)
4477 llassert (uentry_isFunction (ue));
4479 ue->info->fcn->hasGlobs = TRUE;
4482 static void uentry_setHasMods (uentry ue)
4484 llassert (uentry_isFunction (ue));
4486 ue->info->fcn->hasMods = TRUE;
4489 bool uentry_hasGlobs (uentry ue)
4491 if (uentry_isFunction (ue))
4493 return (ue->info->fcn->hasGlobs);
4499 bool uentry_hasStateClauseList (uentry ue)
4501 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4504 bool uentry_hasConditions (uentry ue)
4506 return (uentry_isFunction (ue)
4507 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4508 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4511 stateClauseList uentry_getStateClauseList (uentry ue)
4513 if (!uentry_isFunction (ue))
4515 llassert (uentry_isFunction (ue));
4516 return stateClauseList_undefined;
4519 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4520 return ue->info->fcn->specclauses;
4523 bool uentry_hasMods (uentry ue)
4525 if (uentry_isFunction (ue))
4527 return (ue->info->fcn->hasMods);
4534 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4536 bool hasGlobs, /*@only@*/ globSet globs,
4537 bool hasMods, /*@only@*/ sRefSet mods,
4538 alkind ak, exkind exp,
4539 sstate defstate, nstate isnull,
4543 /*@only@*/ stateClauseList specclauses,
4544 /*@only@*/ warnClause warnclause,
4545 /*@only@*/ fileloc loc)
4547 uentry e = uentry_alloc ();
4550 /* e->shallowCopy = FALSE; */
4554 e->storageclass = SCNONE;
4556 if (ctype_isFunction (ct))
4558 ret = ctype_getReturnType (ct);
4562 if (ctype_isKnown (ct))
4564 llbug (message ("not function: %s", ctype_unparse (ct)));
4567 ret = ctype_unknown;
4570 e->sref = sRef_makeType (ret);
4572 if (ctype_isUA (ret))
4574 sRef_setStateFromType (e->sref, ret);
4577 sRef_setDefined (e->sref, loc);
4578 sRef_setNullState (e->sref, isnull, loc);
4580 sRef_setAliasKind (e->sref, ak, loc);
4581 sRef_setExKind (e->sref, exp, loc);
4582 sRef_setDefState (e->sref, defstate, loc);
4584 e->whereSpecified = loc;
4585 e->whereDefined = fileloc_undefined;
4587 e->isPrivate = FALSE;
4588 e->hasNameError = FALSE;
4592 e->uses = filelocList_new ();
4593 e->warn = warnclause;
4595 e->info = (uinfo) dmalloc (sizeof (*e->info));
4596 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4598 e->info->fcn->exitCode = exitCode;
4599 e->info->fcn->specialCode = sCode;
4600 e->info->fcn->nullPred = nullPred;
4601 e->info->fcn->access = access;
4603 e->info->fcn->specclauses = specclauses;
4604 e->info->fcn->hasGlobs = hasGlobs;
4605 e->info->fcn->globs = globs;
4607 e->info->fcn->hasMods = hasMods;
4608 e->info->fcn->mods = mods;
4610 e->info->fcn->defparams = uentryList_undefined;
4611 e->whereDeclared = fileloc_undefined;
4613 sRef_storeState (e->sref);
4616 e->info->fcn->preconditions = NULL;
4620 e->info->fcn->postconditions = NULL;
4626 static /*@only@*/ uentry
4627 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4628 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4630 uentry e = uentry_alloc ();
4632 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4634 llbuglit ("uentry_makeTagBase: not a tag type");
4637 /* e->shallowCopy = FALSE; */
4641 e->sref = sRef_makeUnknown ();
4642 e->storageclass = SCNONE;
4644 if (fileloc_isSpec (loc))
4646 e->whereSpecified = loc;
4647 e->whereDeclared = fileloc_undefined;
4651 e->whereDeclared = loc;
4652 e->whereSpecified = fileloc_undefined;
4655 e->whereDefined = fileloc_undefined;
4657 e->isPrivate = FALSE;
4658 e->hasNameError = FALSE;
4662 e->uses = filelocList_new ();
4663 e->warn = warnClause_undefined;
4665 e->info = (uinfo) dmalloc (sizeof (*e->info));
4666 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4667 e->info->datatype->abs = qual_createUnknown ();
4668 e->info->datatype->mut = MAYBE;
4669 e->info->datatype->type = rtype;
4671 sRef_storeState (e->sref);
4677 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4678 ctype ct, /*@only@*/ fileloc loc)
4680 uentry e = uentry_alloc ();
4682 /* e->shallowCopy = FALSE; */
4686 e->sref = sRef_makeUnknown ();
4687 e->storageclass = SCNONE;
4689 if (fileloc_isSpec (loc))
4691 e->whereSpecified = loc;
4692 e->whereDeclared = fileloc_undefined;
4696 e->whereDeclared = loc;
4697 e->whereSpecified = fileloc_undefined;
4700 e->whereDefined = fileloc_undefined;
4702 e->isPrivate = FALSE;
4703 e->hasNameError = FALSE;
4707 e->uses = filelocList_new ();
4708 e->warn = warnClause_undefined;
4710 e->info = (uinfo) dmalloc (sizeof (*e->info));
4711 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4712 e->info->iter->access = access;
4713 e->info->iter->mods = sRefSet_undefined;
4714 e->info->iter->globs = globSet_undefined;
4716 sRef_storeState (e->sref);
4721 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4722 /*@only@*/ fileloc loc)
4724 uentry e = uentry_alloc ();
4726 /* e->shallowCopy = FALSE; */
4727 e->ukind = KENDITER;
4728 e->storageclass = SCNONE;
4730 e->utype = ctype_unknown;
4731 e->sref = sRef_makeUnknown ();
4733 if (fileloc_isSpec (loc))
4735 e->whereSpecified = loc;
4736 e->whereDeclared = fileloc_undefined;
4740 e->whereDeclared = loc;
4741 e->whereSpecified = fileloc_undefined;
4744 e->whereDefined = fileloc_undefined;
4746 e->isPrivate = FALSE;
4747 e->hasNameError = FALSE;
4751 e->uses = filelocList_new ();
4752 e->warn = warnClause_undefined;
4754 e->info = (uinfo) dmalloc (sizeof (*e->info));
4755 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4756 e->info->enditer->access = access;
4757 sRef_storeState (e->sref);
4762 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4770 uentry_undump (ekind kind, fileloc loc, char **s)
4774 DPRINTF (("Uentry undump: %s", *s));
4778 reader_checkChar (s, '!');
4779 reader_checkChar (s, '.');
4780 ue = uentry_makeElipsisMarker ();
4784 ctype ct = ctype_undump (s);
4798 reader_checkChar (s, '|');
4800 if (reader_optCheckChar (s, '@'))
4802 tkind = vkind_fromInt (reader_getInt (s));
4803 reader_checkChar (s, '|');
4810 if (reader_optCheckChar (s, '$'))
4812 defstate = SS_UNKNOWN;
4813 isnull = NS_UNKNOWN;
4814 aliased = AK_IMPTEMP;
4816 checked = CH_UNKNOWN;
4818 else if (reader_optCheckChar (s, '&'))
4820 defstate = SS_DEFINED;
4821 isnull = NS_UNKNOWN;
4822 aliased = AK_IMPTEMP;
4824 checked = CH_UNKNOWN;
4826 else if (reader_optCheckChar (s, '^'))
4828 defstate = SS_UNKNOWN;
4829 isnull = NS_UNKNOWN;
4830 aliased = AK_IMPTEMP;
4832 checked = CH_UNKNOWN;
4836 defstate = sstate_fromInt (reader_getInt (s));
4837 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4838 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4840 if (reader_optCheckChar (s, '&'))
4843 checked = CH_UNKNOWN;
4847 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4848 advanceField (s); checked = (chkind) (reader_getInt (s));
4853 name = reader_getStringWord (s);
4855 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4857 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4858 isnull, aliased, exp,
4859 checked, fileloc_copy (loc));
4872 advanceField (s); abstract = qual_abstractFromCodeChar (reader_loadChar (s));
4873 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4874 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4875 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4876 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4877 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4878 advanceField (s); rtype = ctype_undump (s);
4880 name = reader_getStringWord (s);
4881 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4882 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4883 aliased, exp, defstate, isnull,
4884 fileloc_copy (loc));
4901 stateClauseList specclauses = stateClauseList_undefined;
4902 warnClause warnclause = warnClause_undefined;
4904 if (reader_optCheckChar (s, '$'))
4906 defstate = SS_DEFINED;
4907 isnull = NS_UNKNOWN;
4908 exitCode = XK_UNKNOWN;
4910 nullPred = qual_createUnknown ();
4914 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4915 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4916 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4917 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4918 advanceField (s); nullPred = qual_undump (s);
4921 if (reader_optCheckChar (s, '$'))
4924 globs = globSet_undefined;
4926 mods = sRefSet_undefined;
4928 else if (reader_optCheckChar (s, '^'))
4931 globs = globSet_undefined;
4933 mods = sRefSet_undefined;
4937 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4938 advanceField (s); globs = globSet_undump (s);
4939 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4940 advanceField (s); mods = sRefSet_undump (s);
4943 if (reader_optCheckChar (s, '$'))
4950 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4951 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4954 advanceField (s); access = typeIdSet_undump (s);
4957 ** Optional clauses: Start with @<code>:
4960 while (reader_optCheckChar (s, '@'))
4962 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4964 reader_checkChar (s, ':');
4965 warnclause = warnClause_undump (s);
4967 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4969 reader_checkChar (s, ':');
4970 specclauses = stateClauseList_undump (s);
4978 advanceName (s); name = reader_getStringWord (s);
4980 ue = uentry_makeFunctionBase (name, ct, access,
4983 ak, exp, defstate, isnull,
4984 exitCode, specc, nullPred,
4987 fileloc_copy (loc));
4988 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4995 advanceField (s); access = typeIdSet_undump (s);
4996 advanceName (s); name = reader_getStringWord (s);
4998 ue = uentry_makeIterBase (name, access, ct,
4999 fileloc_copy (loc));
5006 advanceField (s); access = typeIdSet_undump (s);
5007 advanceName (s); name = reader_getStringWord (s);
5009 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
5019 if (reader_optCheckChar (s, '$'))
5021 val = multiVal_undefined;
5022 access = typeIdSet_undefined;
5023 nullstate = NS_UNKNOWN;
5027 advanceField (s); val = multiVal_undump (s);
5028 advanceField (s); access = typeIdSet_undump (s);
5029 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
5032 advanceName (s); name = reader_getStringWord (s);
5034 ue = uentry_makeConstantBase (name, ct, access,
5035 nullstate, fileloc_copy (loc), val);
5044 advanceField (s); rtype = ctype_undump (s);
5045 advanceName (s); name = reader_getStringWord (s);
5046 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5050 llcontbuglit ("uentry_undump: invalid");
5051 ue = uentry_undefined;
5054 llcontbuglit ("uentry_undump: elips marker");
5055 ue = uentry_undefined;
5064 uentry_dump (uentry v)
5066 return (uentry_dumpAux (v, FALSE));
5070 uentry_dumpParam (uentry v)
5072 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5073 ("dump: %s", uentry_unparseFull (v)));
5075 return (uentry_dumpAux (v, TRUE));
5079 uentry_dumpAux (uentry v, bool isParam)
5081 llassert (uentry_isValid (v));
5082 llassert (!uentry_isGlobalMarker (v));
5084 DPRINTF (("Dump uentry: [%p]", v));
5085 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5090 llcontbuglit ("uentry_dump: invalid entry");
5091 return cstring_undefined;
5093 return (message ("!."));
5097 vkind vk = v->info->var->kind;
5098 sstate dss = sRef_getDefState (v->sref);
5099 nstate nst = sRef_getNullState (v->sref);
5100 alkind alk = sRef_getAliasKind (v->sref);
5101 exkind exk = sRef_getExKind (v->sref);
5102 chkind chk = v->info->var->checked;
5104 DPRINTF (("Dumping var"));
5106 if (dss == SS_UNKNOWN
5107 && nst == NS_UNKNOWN
5108 && alk == AK_IMPTEMP
5109 && exk == XO_UNKNOWN
5110 && chk == CH_UNKNOWN)
5112 sdump = cstring_makeLiteral ("$");
5114 else if (dss == SS_DEFINED
5115 && nst == NS_UNKNOWN
5116 && alk == AK_IMPTEMP
5117 && exk == XO_UNKNOWN
5118 && chk == CH_UNKNOWN)
5120 sdump = cstring_makeLiteral ("&");
5122 else if (dss == SS_UNKNOWN
5123 && nst == NS_UNKNOWN
5124 && alk == AK_UNKNOWN
5125 && exk == XO_UNKNOWN
5126 && chk == CH_UNKNOWN)
5128 sdump = cstring_makeLiteral ("^");
5130 else if (exk == XO_UNKNOWN
5131 && chk == CH_UNKNOWN)
5133 sdump = message ("%d@%d@%d&",
5140 sdump = message ("%d@%d@%d@%d@%d",
5151 return (message ("%q|@%d|%q#%s",
5152 ctype_dump (v->utype),
5155 isParam ? cstring_undefined : v->uname));
5159 return (message ("%q|%q#%s",
5160 ctype_dump (v->utype),
5162 isParam ? cstring_undefined : v->uname));
5168 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5170 exkind_unparse (sRef_getExKind (v->sref)),
5171 ctype_unparse (v->utype), (int) v->utype));
5174 return (message ("%q@%c@%s@%d@%d@%d@%d@%q#%s",
5175 ctype_dump (v->utype),
5176 qual_abstractCode (v->info->datatype->abs),
5177 ynm_unparseCode (v->info->datatype->mut),
5178 (int) sRef_getDefState (v->sref),
5179 (int) sRef_getNullState (v->sref),
5180 (int) sRef_getAliasKind (v->sref),
5181 (int) sRef_getExKind (v->sref),
5182 ctype_dump (v->info->datatype->type),
5186 cstring sdump, gdump, adump, xdump;
5187 alkind alk = sRef_getAliasKind (v->sref);
5188 exkind exk = sRef_getExKind (v->sref);
5190 if (sRef_getDefState (v->sref) == SS_DEFINED
5191 && !nstate_isKnown (sRef_getNullState (v->sref))
5192 && !exitkind_isKnown (v->info->fcn->exitCode)
5193 && v->info->fcn->specialCode == SPC_NONE
5194 && qual_isUnknown (v->info->fcn->nullPred))
5196 sdump = cstring_makeLiteral ("$");
5200 sdump = message ("@%d@%d@%d@%d@%x",
5201 (int) sRef_getDefState (v->sref),
5202 (int) sRef_getNullState (v->sref),
5203 (int) v->info->fcn->exitCode,
5204 (int) v->info->fcn->specialCode,
5205 qual_dump (v->info->fcn->nullPred));
5208 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5210 gdump = cstring_makeLiteral ("$");
5212 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5213 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5215 gdump = cstring_makeLiteral ("^");
5219 gdump = message ("@%s@%q@%s@%q",
5220 bool_dump (uentry_hasGlobs (v)),
5221 globSet_dump (uentry_getGlobs (v)),
5222 bool_dump (uentry_hasMods (v)),
5223 sRefSet_dump (uentry_getMods (v)));
5226 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5228 adump = cstring_makeLiteral ("$");
5232 adump = message ("@%d@%d", (int) alk, (int) exk);
5235 xdump = cstring_undefined;
5237 if (uentry_hasWarning (v))
5239 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5242 if (uentry_hasStateClauseList (v))
5244 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5247 return (message ("%q%q%q%q@%q%q#%s",
5248 ctype_dump (v->utype),
5252 typeIdSet_dump (uentry_accessType (v)),
5257 return (message ("%q@%q#%s",
5258 ctype_dump (v->utype),
5259 typeIdSet_dump (v->info->iter->access),
5262 return (message ("%q@%q#%s",
5263 ctype_dump (v->utype),
5264 typeIdSet_dump (uentry_accessType (v)),
5271 if (multiVal_isUnknown (uentry_getConstantValue (v))
5272 && typeIdSet_isEmpty (uentry_accessType (v))
5273 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5275 sdump = cstring_makeLiteral ("$");
5279 sdump = message ("@%q@%q@%d",
5280 multiVal_dump (uentry_getConstantValue (v)),
5281 typeIdSet_dump (uentry_accessType (v)),
5282 (int) sRef_getNullState (v->sref));
5285 return (message ("%q%q#%s",
5286 ctype_dump (v->utype),
5293 return (message ("%q@%q#%s",
5294 ctype_dump (v->utype),
5295 ctype_dump (v->info->datatype->type), v->uname));
5302 uentry_unparseAbbrev (uentry v)
5304 if (!uentry_isVariable (v))
5306 llcontbuglit ("uentry_unparseAbbrev: not variable");
5307 return uentry_unparse (v);
5310 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5314 uentry_unparse (uentry v)
5318 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5319 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5321 st = uentry_getName (v);
5323 if (cstring_isDefined (st))
5325 return (ctype_unparseDeclaration (v->utype, st));
5330 return (cstring_copy (ctype_unparse (v->utype)));
5335 uentry_unparseFull (uentry v)
5337 if (uentry_isUndefined (v))
5339 return (cstring_makeLiteral ("<undefined>"));
5345 res = message ("[%p] %s %s: %s [spec: %q; decl: %q; def: %q]",
5346 v, ekind_unparse (v->ukind), v->uname,
5347 ctype_unparse (v->utype),
5348 fileloc_unparse (uentry_whereSpecified (v)),
5349 fileloc_unparse (uentry_whereDeclared (v)),
5350 fileloc_unparse (uentry_whereDefined (v)));
5352 DPRINTF (("uentry: %s", res));
5354 if (uentry_isDatatype (v))
5356 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5359 (ctype_isDefined (v->info->datatype->type)
5360 ? v->info->datatype->type : ctype_unknown),
5361 ynm_unparse (v->info->datatype->mut),
5362 qual_unparse (v->info->datatype->abs),
5363 sRef_unparseState (v->sref));
5365 else if (uentry_isFunction (v))
5367 res = message ("%q / sref: %q / mods: %q / "
5368 "globs: %q / clauses: %q / pre: %q / post: %q",
5370 sRef_unparseFull (v->sref),
5371 sRefSet_unparse (v->info->fcn->mods),
5372 globSet_unparse (v->info->fcn->globs),
5373 stateClauseList_unparse (v->info->fcn->specclauses),
5374 functionConstraint_unparse (v->info->fcn->preconditions),
5375 functionConstraint_unparse (v->info->fcn->postconditions));
5377 else if (uentry_isIter (v))
5379 res = message ("%q / sref: %q",
5381 sRef_unparseFull (v->sref));
5383 else if (uentry_isVariable (v))
5385 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5387 sRef_unparseFull (v->sref),
5388 (int) v->info->var->kind,
5389 (int) v->info->var->defstate,
5390 (int) v->info->var->nullstate,
5392 DPRINTF (("sref: [%p]", v->sref));
5393 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5394 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5396 else if (uentry_isConstant (v))
5398 res = message ("%q = %q / %q",
5399 res, multiVal_unparse (uentry_getConstantValue (v)),
5400 sRef_unparseFull (v->sref));
5404 res = message ("%q :: %q", res, uentry_unparse (v));
5411 bool uentry_hasAccessType (uentry e)
5413 if (uentry_isValid (e))
5418 return (!typeIdSet_isEmpty (e->info->iter->access));
5420 return (!typeIdSet_isEmpty (e->info->enditer->access));
5422 return (!typeIdSet_isEmpty (e->info->fcn->access));
5425 return (!typeIdSet_isEmpty (e->info->uconst->access));
5434 typeIdSet uentry_accessType (uentry e)
5436 if (uentry_isValid (e))
5441 return (e->info->iter->access);
5443 return (e->info->enditer->access);
5445 return (e->info->fcn->access);
5448 return (e->info->uconst->access);
5454 return typeIdSet_undefined;
5458 uentry_isVariable (uentry e)
5460 return (uentry_isVar (e));
5464 uentry_isSpecified (uentry e)
5466 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5470 uentry_isReallySpecified (uentry e)
5472 return (uentry_isValid (e)
5473 && fileloc_isRealSpec (e->whereSpecified));
5477 uentry_isVar (uentry e)
5479 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5483 uentry_isFakeTag (uentry e)
5485 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5489 uentry_isDatatype (uentry e)
5491 return (!uentry_isUndefined (e) &&
5492 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5493 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5497 uentry_setAbstract (uentry e)
5501 llassert (uentry_isDatatype (e)
5502 && (qual_isUnknown (e->info->datatype->abs)));
5504 oldid = ctype_typeId (e->info->datatype->type);
5505 e->info->datatype->abs = qual_createAbstract ();
5506 e->info->datatype->type = ctype_createAbstract (oldid);
5510 uentry_setConcrete (uentry e)
5512 llassert (uentry_isDatatype (e)
5513 && (qual_isUnknown (e->info->datatype->abs)
5514 || qual_isConcrete (e->info->datatype->abs)));
5516 e->info->datatype->abs = qual_createConcrete ();
5520 uentry_isAbstractDatatype (uentry e)
5522 return (uentry_isDatatype (e)
5523 && (qual_isEitherAbstract (e->info->datatype->abs)));
5527 uentry_isMaybeAbstract (uentry e)
5529 return (uentry_isDatatype (e)
5530 && (!qual_isConcrete (e->info->datatype->abs)));
5534 uentry_isMutableDatatype (uentry e)
5536 if (uentry_isDatatype (e))
5538 if (ctype_isNumAbstract (e->info->datatype->type))
5544 return ynm_toBoolRelaxed (e->info->datatype->mut);
5552 uentry_isRefCountedDatatype (uentry e)
5554 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5558 uentry_isParam (uentry u)
5560 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5561 || u->info->var->kind == VKYIELDPARAM));
5565 uentry_isExpandedMacro (uentry u)
5567 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5571 uentry_isSefParam (uentry u)
5573 return (uentry_isVariable (u)
5574 && (u->info->var->kind == VKSEFPARAM
5575 || u->info->var->kind == VKREFSEFPARAM
5576 || u->info->var->kind == VKSEFRETPARAM
5577 || u->info->var->kind == VKREFSEFRETPARAM));
5581 uentry_isRefParam (uentry u)
5583 return (uentry_isVariable (u)
5584 && (u->info->var->kind == VKREFPARAM
5585 || u->info->var->kind == VKREFYIELDPARAM
5586 || u->info->var->kind == VKREFSEFPARAM
5587 || u->info->var->kind == VKREFSEFRETPARAM));
5591 uentry_isAnyParam (uentry u)
5593 return (uentry_isVariable (u)
5594 && ((u->info->var->kind == VKPARAM)
5595 || (u->info->var->kind == VKSEFPARAM)
5596 || (u->info->var->kind == VKYIELDPARAM)
5597 || (u->info->var->kind == VKRETPARAM)
5598 || (u->info->var->kind == VKSEFRETPARAM)));
5602 uentry_getDefState (uentry u)
5604 if (uentry_isValid (u))
5606 return (sRef_getDefState (u->sref));
5610 return (SS_UNKNOWN);
5615 uentry_isOut (uentry u)
5617 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5618 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5622 uentry_isPartial (uentry u)
5624 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5625 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5629 uentry_isStateSpecial (uentry u)
5631 return ((uentry_isVariable (u)
5632 && (u->info->var->defstate == SS_SPECIAL))
5633 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5636 exitkind uentry_getExitCode (uentry ue)
5638 if (uentry_isFunction (ue))
5640 return ue->info->fcn->exitCode;
5648 qual uentry_nullPred (uentry u)
5650 llassert (uentry_isRealFunction (u));
5652 if (uentry_isFunction (u))
5654 return (u->info->fcn->nullPred);
5658 return qual_createUnknown ();
5663 ** Note for variables, this is checking the declared state, not the current state.
5667 uentry_possiblyNull (uentry u)
5669 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5670 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5674 uentry_getAliasKind (uentry u)
5676 if (uentry_isValid (u))
5678 return (sRef_getAliasKind (uentry_getSref (u)));
5687 uentry_getExpKind (uentry u)
5689 if (uentry_isValid (u))
5691 return (sRef_getExKind (uentry_getSref (u)));
5700 uentry_isIter (uentry e)
5702 return (!uentry_isUndefined (e) && e->ukind == KITER);
5706 uentry_isEndIter (uentry e)
5708 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5712 uentry_isRealFunction (uentry e)
5714 return (uentry_isFunction (e) ||
5715 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5719 uentry_hasName (uentry e)
5721 if (uentry_isValid (e))
5723 cstring s = e->uname;
5725 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5726 || uentry_isFakeTag (e)));
5735 ** Returns true for fake tags.
5736 ** This is used for dumping the library
5739 bool uentry_hasRealName (uentry e)
5741 return (uentry_isValid (e)
5742 && cstring_isNonEmpty (e->uname)
5743 && !uentry_isGlobalMarker (e));
5747 /*@observer@*/ globSet
5748 uentry_getGlobs (uentry l)
5750 if (uentry_isInvalid (l))
5752 return globSet_undefined;
5755 if (uentry_isFunction (l))
5757 return l->info->fcn->globs;
5759 else if (uentry_isIter (l))
5761 return l->info->iter->globs;
5763 else if (uentry_isEndIter (l))
5765 return globSet_undefined;
5769 if (l->ukind == KVAR)
5771 llcontbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5773 ekind_unparse (l->ukind)));
5777 llcontbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5779 ekind_unparse (l->ukind)));
5782 return globSet_undefined;
5787 /* Make Microsoft VC++ happy */
5788 # pragma warning (disable : 4715)
5791 /*@observer@*/ sRefSet
5792 uentry_getMods (uentry l)
5794 llassert (uentry_isValid (l));
5796 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5798 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5799 return sRefSet_undefined;
5802 if (uentry_isFunction (l))
5804 return l->info->fcn->mods;
5806 else if (uentry_isIter (l))
5808 return l->info->iter->mods;
5810 else if (uentry_isEndIter (l))
5812 return sRefSet_undefined;
5821 uentry_getKind (uentry e)
5823 llassert (uentry_isValid (e));
5827 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5829 llassert (uentry_isEitherConstant (e));
5830 return (sRef_getValue (e->sref));
5833 /*@observer@*/ uentryList
5834 uentry_getParams (uentry l)
5836 if (uentry_isInvalid (l)) return uentryList_undefined;
5843 ctype ct = l->utype;
5845 if (ctype_isFunction (ct))
5847 return (ctype_argsFunction (ct));
5851 return uentryList_undefined;
5856 ctype ct = l->utype;
5858 /*drl 12/10/2002 changed to fix bug involving multiple redefines of library functions in macros. Bug was reported by Malcolm Parsons
5860 Old code was simplly llassert (ctype_isFunction (ct) );
5863 llassert (ctype_isFunction (ct) || context_inMacro() );
5865 return (ctype_argsFunction (ct));
5872 /*@observer@*/ cstring
5873 uentry_rawName (uentry e)
5875 if (uentry_isValid (e))
5881 return cstring_undefined;
5886 uentry_getOptName (uentry e)
5888 cstring s = uentry_getName (e);
5890 if (cstring_isDefined (s))
5892 s = cstring_appendChar (s, ' ');
5899 uentry_getName (uentry e)
5901 cstring ret = cstring_undefined;
5903 if (uentry_isValid (e))
5905 if (uentry_isAnyTag (e))
5907 ret = fixTagName (e->uname);
5909 else if (uentry_isAnyParam (e))
5911 ret = cstring_copy (fixParamName (e->uname));
5915 ret = cstring_copy (e->uname);
5922 cstring uentry_observeRealName (uentry e)
5924 cstring ret = cstring_undefined;
5926 if (uentry_isValid (e))
5928 if (uentry_isAnyTag (e))
5930 if (isFakeTag (e->uname))
5932 ret = cstring_undefined;
5936 ret = plainTagName (e->uname);
5939 else if (uentry_isAnyParam (e))
5941 ret = fixParamName (e->uname);
5952 cstring uentry_getRealName (uentry e)
5954 if (uentry_isValid (e))
5956 if (uentry_isAnyTag (e))
5958 return (cstring_undefined);
5965 return cstring_undefined;
5968 ctype uentry_getType (uentry e)
5970 if (uentry_isValid (e))
5976 return ctype_unknown;
5980 fileloc uentry_whereLast (uentry e)
5984 if (uentry_isInvalid (e))
5986 return fileloc_undefined;
5989 loc = e->whereDefined;
5991 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5996 loc = uentry_whereDeclared (e);
5998 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
6003 loc = uentry_whereSpecified (e);
6007 fileloc uentry_whereEither (uentry e)
6009 if (uentry_isInvalid (e)) return fileloc_undefined;
6011 if (fileloc_isDefined (e->whereDefined)
6012 && !fileloc_isExternal (e->whereDefined))
6014 return e->whereDefined;
6016 else if (fileloc_isDefined (e->whereDeclared))
6018 return e->whereDeclared;
6022 return e->whereSpecified;
6026 fileloc uentry_whereSpecified (uentry e)
6028 if (uentry_isInvalid (e)) return fileloc_undefined;
6030 return (e->whereSpecified);
6033 fileloc uentry_whereDefined (uentry e)
6035 if (uentry_isInvalid (e)) return fileloc_undefined;
6037 return (e->whereDefined);
6040 fileloc uentry_whereDeclared (uentry e)
6042 if (uentry_isInvalid (e)) return fileloc_undefined;
6044 return (e->whereDeclared);
6047 /*@observer@*/ fileloc
6048 uentry_whereEarliest (uentry e)
6050 if (uentry_isInvalid (e)) return fileloc_undefined;
6052 if (fileloc_isDefined (e->whereSpecified))
6054 return (e->whereSpecified);
6056 else if (fileloc_isDefined (e->whereDeclared))
6058 return (e->whereDeclared);
6062 return e->whereDefined;
6067 uentry_setFunctionDefined (uentry e, fileloc loc)
6069 if (uentry_isValid (e))
6071 llassert (uentry_isFunction (e));
6073 if (fileloc_isUndefined (e->whereDeclared))
6075 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6078 if (!fileloc_isDefined (e->whereDefined))
6080 e->whereDefined = fileloc_update (e->whereDefined, loc);
6086 uentry_setDeclDef (uentry e, fileloc f)
6088 uentry_setDeclared (e, f);
6090 if (!uentry_isFunction (e)
6091 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6093 uentry_setDefined (e, f);
6098 uentry_setDeclaredForce (uentry e, fileloc f)
6100 llassert (uentry_isValid (e));
6101 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6105 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6107 llassert (uentry_isValid (e));
6108 fileloc_free (e->whereDeclared);
6109 e->whereDeclared = f;
6113 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6117 llassert (uentry_isValid (e));
6118 oldloc = e->whereDeclared;
6120 if (fileloc_isDefined (oldloc))
6122 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6124 e->whereDeclared = f;
6125 fileloc_free (oldloc);
6134 e->whereDeclared = f;
6135 fileloc_free (oldloc);
6140 uentry_setDeclared (uentry e, fileloc f)
6144 llassert (uentry_isValid (e));
6145 oldloc = e->whereDeclared;
6147 if (fileloc_isDefined (oldloc))
6149 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6151 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6160 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6165 uentry_clearDefined (uentry e)
6167 if (uentry_isValid (e))
6169 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6174 uentry_setDefined (uentry e, fileloc f)
6178 llassert (uentry_isValid (e));
6179 oldloc = e->whereDefined;
6181 if (fileloc_isDefined (oldloc))
6183 if (fileloc_isLib (oldloc)
6184 || fileloc_isImport (oldloc)
6185 || fileloc_isBuiltin (oldloc)
6186 || fileloc_isPreproc (oldloc))
6188 e->whereDefined = fileloc_update (e->whereDefined, f);
6192 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6198 if (optgenerror (FLG_REDEF,
6199 message ("%s %q redefined",
6200 ekind_capName (e->ukind),
6201 uentry_getName (e)),
6204 llgenindentmsg (message ("Previous definition of %q",
6205 uentry_getName (e)),
6213 e->whereDefined = fileloc_update (e->whereDefined, f);
6218 uentry_isCodeDefined (uentry e)
6220 llassert (uentry_isValid (e));
6222 return (fileloc_isDefined (e->whereDefined));
6226 uentry_isDeclared (uentry e)
6228 if (uentry_isValid (e))
6230 return (fileloc_isDefined (e->whereDeclared));
6236 sRef uentry_getSref (uentry e)
6238 /* not true, used for functions too (but shouldn't be? */
6239 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6241 if (uentry_isInvalid (e)) return sRef_undefined;
6246 sRef uentry_getOrigSref (uentry e)
6248 /* evans 2003-04-12 - removed for now */
6249 /* evans 2001-09-09 - need to fix this
6250 if (uentry_isValid (e))
6252 if (uentry_isVariable (e))
6254 return e->info->var->origsref;
6258 sRef sr = sRef_copy (uentry_getSref (e));
6260 sRef_resetState (sr);
6261 sRef_clearDerived (sr);
6267 return sRef_undefined;
6271 if (uentry_isValid (e))
6273 sRef sr = sRef_copy (uentry_getSref (e));
6275 sRef_resetState (sr);
6276 sRef_clearDerived (sr);
6278 if (uentry_isVariable (e))
6280 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6281 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6288 return sRef_undefined;
6293 ** requires: uentry e is not in a hashed symbol table
6297 uentry_setName (uentry e, /*@only@*/ cstring n)
6299 llassert (uentry_isValid (e));
6301 cstring_free (e->uname);
6306 uentry_setType (uentry e, ctype t)
6308 if (uentry_isValid (e))
6311 sRef_setType (e->sref, t);
6316 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6319 ctype rettype = ctype_unknown;
6321 llassert (uentry_isValid (ue));
6323 uentry_convertVarFunction (ue);
6324 llassert (uentry_isFunction (ue));
6326 rct = ctype_realType (ue->utype);
6328 if (ctype_isFunction (rct))
6330 rettype = ctype_getReturnType (rct);
6333 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6337 uentry_setRefParam (uentry e)
6339 if (!uentry_isVar (e))
6341 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6345 if (e->info->var->kind == VKSEFPARAM)
6347 e->info->var->kind = VKREFSEFPARAM;
6349 else if (e->info->var->kind == VKSEFRETPARAM)
6351 e->info->var->kind = VKREFSEFRETPARAM;
6353 else if (e->info->var->kind == VKYIELDPARAM)
6355 e->info->var->kind = VKREFYIELDPARAM;
6359 e->info->var->kind = VKREFPARAM;
6365 uentry_setParam (uentry e)
6367 if (!uentry_isVar (e))
6369 if (uentry_isElipsisMarker (e))
6375 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6382 if (e->info->var->kind == VKYIELDPARAM
6383 || e->info->var->kind == VKSEFPARAM
6384 || e->info->var->kind == VKSEFRETPARAM)
6390 e->info->var->kind = VKPARAM;
6394 e->uname = makeParam (e->uname);
6395 cstring_free (oldname);
6400 uentry_setSref (uentry e, sRef s)
6402 if (uentry_isValid (e))
6404 if (sRef_isValid (e->sref))
6406 sRef_mergeStateQuietReverse (e->sref, s);
6410 e->sref = sRef_saveCopy (s);
6416 uentry_getAbstractType (uentry e)
6418 llassert (uentry_isDatatype (e));
6421 ** This assertion removed.
6422 ** Okay to have undefined type, for system types
6424 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6425 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6430 if (ctype_isUndefined (e->info->datatype->type))
6432 return ctype_unknown;
6436 ** Sadly, a kludge...
6439 if (ctype_isUserBool (e->info->datatype->type)) {
6443 return e->info->datatype->type;
6446 ctype uentry_getRealType (uentry e)
6449 typeId uid = typeId_invalid;
6451 if (uentry_isInvalid (e))
6453 return ctype_unknown;
6456 if (!uentry_isDatatype (e))
6458 /* This shouldn't happen, except when types are redeclared in strange ways */
6459 return ctype_unknown;
6462 if (uentry_isAnyTag (e))
6467 if (uentry_isAbstractType (e))
6469 ct = uentry_getAbstractType (e);
6471 if (ctype_isManifestBool (ct)) {
6475 llassert (ctype_isUA (ct));
6477 uid = ctype_typeId (ct);
6479 if (!context_hasAccess (uid))
6485 ct = uentry_getType (e);
6487 /* if (ctype_isUserBool (ct)) return ct; */
6489 if (ctype_isManifestBool (ct)) {
6493 if (ctype_isUA (ct))
6495 typeId iid = ctype_typeId (ct);
6497 if (typeId_equal (iid, uid))
6499 llcontbug (message ("uentry_getRealType: recursive type! %s",
6500 ctype_unparse (ct)));
6505 /* evs 2000-07-25: possible infinite recursion ? */
6506 uentry ue2 = usymtab_getTypeEntry (iid);
6510 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6511 return ctype_unknown;
6514 return uentry_getRealType (ue2);
6523 ctype uentry_getForceRealType (uentry e)
6526 typeId uid = typeId_invalid;
6528 if (uentry_isInvalid (e))
6530 return ctype_unknown;
6533 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6535 if (uentry_isAnyTag (e))
6540 if (uentry_isAbstractType (e))
6542 ct = uentry_getAbstractType (e);
6543 llassert (ctype_isUA (ct));
6545 uid = ctype_typeId (ct);
6546 /* no check for access! */
6549 ct = uentry_getType (e);
6551 /* evs 2000-07-25 */
6552 /* if (ctype_isUserBool (ct)) return ct; */
6554 if (ctype_isManifestBool (ct)) {
6558 if (ctype_isUA (ct))
6560 typeId iid = ctype_typeId (ct);
6562 if (typeId_equal (iid, uid))
6564 llcontbug (message ("uentry_getRealType: recursive type! %s",
6565 ctype_unparse (ct)));
6570 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6579 uentry uentry_nameCopy (cstring name, uentry e)
6581 uentry enew = uentry_alloc ();
6583 llassert (uentry_isValid (e));
6585 /* enew->shallowCopy = FALSE; */
6586 enew->ukind = e->ukind;
6588 enew->utype = e->utype;
6589 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6590 enew->whereDefined = fileloc_copy (e->whereDefined);
6591 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6592 enew->sref = sRef_copy (e->sref);
6593 enew->used = e->used;
6595 enew->isPrivate = e->isPrivate;
6596 enew->hasNameError = FALSE;
6598 enew->uses = filelocList_new ();
6599 enew->warn = warnClause_undefined;
6601 enew->storageclass = e->storageclass;
6602 enew->info = uinfo_copy (e->info, e->ukind);
6608 uentry_setDatatype (uentry e, typeId uid)
6610 llassert (uentry_isDatatype (e));
6612 if (uentry_isAbstractType (e))
6614 if (qual_isNumAbstract (e->info->datatype->abs))
6616 e->info->datatype->type = ctype_createNumAbstract (uid);
6620 llassert (qual_isAbstract (e->info->datatype->abs));
6621 e->info->datatype->type = ctype_createAbstract (uid);
6626 e->info->datatype->type = ctype_createUser (uid);
6631 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6632 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6635 llassert (uentry_isValid (e));
6637 if (fileloc_isSpec (f) || fileloc_isImport (f))
6639 e->whereSpecified = f;
6640 e->whereDeclared = fileloc_undefined;
6641 e->whereDefined = fileloc_undefined;
6645 e->whereSpecified = fileloc_undefined;
6646 e->whereDeclared = f;
6647 e->whereDefined = fileloc_undefined;
6650 llassert (fileloc_storable (f));
6654 ucinfo_free (/*@only@*/ ucinfo u)
6660 uvinfo_free (/*@only@*/ uvinfo u)
6662 /*drl7x added 6/29/01 */
6663 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6668 udinfo_free (/*@only@*/ udinfo u)
6674 ufinfo_free (/*@only@*/ ufinfo u)
6676 globSet_free (u->globs);
6677 sRefSet_free (u->mods);
6678 stateClauseList_free (u->specclauses);
6683 uiinfo_free (/*@only@*/ uiinfo u)
6689 ueinfo_free (/*@only@*/ ueinfo u)
6694 static /*@only@*/ ucinfo
6695 ucinfo_copy (ucinfo u)
6697 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6698 ret->access = u->access;
6699 ret->macro = u->macro;
6703 static /*@only@*/ uvinfo
6704 uvinfo_copy (uvinfo u)
6706 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6708 ret->kind = u->kind;
6709 ret->nullstate = u->nullstate;
6710 ret->defstate = u->defstate;
6711 ret->checked = u->checked;
6714 /* drl added 07-02-001 */
6715 /* copy null terminated information */
6717 if (u->bufinfo != NULL)
6719 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6720 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6721 ret->bufinfo->size = u->bufinfo->size;
6722 ret->bufinfo->len = u->bufinfo->len;
6727 ret->bufinfo = NULL;
6733 static /*@only@*/ udinfo
6734 udinfo_copy (udinfo u)
6736 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6740 ret->type = u->type;
6745 static /*@only@*/ ufinfo
6746 ufinfo_copy (ufinfo u)
6748 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6750 ret->hasGlobs = u->hasGlobs;
6751 ret->hasMods = u->hasMods;
6752 ret->exitCode = u->exitCode;
6753 ret->specialCode = u->specialCode;
6754 ret->nullPred = u->nullPred;
6755 ret->access = u->access;
6756 ret->globs = globSet_newCopy (u->globs);
6757 ret->mods = sRefSet_newCopy (u->mods);
6758 ret->defparams = u->defparams;
6759 ret->specclauses = stateClauseList_copy (u->specclauses);
6761 ret->preconditions = functionConstraint_copy (u->preconditions);
6762 ret->postconditions = functionConstraint_copy (u->postconditions);
6767 static /*@only@*/ uiinfo
6768 uiinfo_copy (uiinfo u)
6770 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6772 ret->access = u->access;
6773 ret->globs = globSet_newCopy (u->globs);
6774 ret->mods = sRefSet_newCopy (u->mods);
6779 static /*@only@*/ ueinfo
6780 ueinfo_copy (ueinfo u)
6782 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6784 ret->access = u->access;
6789 uinfo_free (uinfo u, ekind kind)
6794 case KCONST: ucinfo_free (u->uconst); break;
6795 case KVAR: uvinfo_free (u->var); break;
6799 case KDATATYPE: udinfo_free (u->datatype); break;
6800 case KFCN: ufinfo_free (u->fcn); break;
6801 case KITER: uiinfo_free (u->iter); break;
6802 case KENDITER: ueinfo_free (u->enditer); break;
6803 case KELIPSMARKER: break;
6804 case KINVALID: break;
6810 static /*@only@*/ /*@null@*/ uinfo
6811 uinfo_copy (uinfo u, ekind kind)
6813 if (kind == KELIPSMARKER || kind == KINVALID)
6819 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6824 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6825 case KVAR: ret->var = uvinfo_copy (u->var); break;
6829 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6830 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6831 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6832 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6840 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6842 filelocList_free (e->uses);
6843 cstring_free (e->uname);
6845 uinfo_free (e->info, e->ukind);
6847 fileloc_free (e->whereSpecified);
6848 fileloc_free (e->whereDefined);
6849 fileloc_free (e->whereDeclared);
6851 warnClause_free (e->warn);
6857 extern void uentry_markOwned (/*@owned@*/ uentry u)
6859 sfreeEventually (u);
6863 uentry_free (/*@only@*/ uentry e)
6865 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6867 uentry_reallyFree (e);
6872 ** For uentry's in the global or file scope
6876 uentry_freeComplete (/*@only@*/ uentry e)
6878 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6880 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6881 /*@i@*/ sRef_free (e->sref);
6882 e->sref = sRef_undefined;
6883 uentry_reallyFree (e);
6888 ** requires old->kind != new->kind, old->uname = new->uname
6892 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6894 llassert (uentry_isValid (old));
6895 llassert (uentry_isValid (unew));
6897 if ((uentry_isEitherConstant (unew) || uentry_isDatatype (unew))
6898 && (fileloc_isPreproc (uentry_whereDeclared (old))
6899 || ctype_isUnknown (old->utype))
6900 && !uentry_isSpecified (old))
6908 if (!uentry_isDeclared (old))
6910 if (uentry_isSpecified (old))
6912 if (uentry_isSpecified (unew))
6914 llbuglit ("Respecification!");
6916 else if (uentry_isDeclared (unew))
6920 message ("%s %q inconsistently declared as %s: %t",
6921 ekind_capName (old->ukind),
6922 uentry_getName (unew),
6923 ekind_unparseLong (unew->ukind),
6925 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6927 uentry_showWhereLastKind (old);
6939 message ("%s %q inconsistently declared as %s: %t",
6940 ekind_capName (old->ukind),
6941 uentry_getName (unew),
6942 ekind_unparseLong (unew->ukind),
6944 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6946 uentry_showWhereLastKind (old);
6952 llassert (uentry_isDeclared (unew));
6954 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6955 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6959 message ("%s %q inconsistently redeclared as %s",
6960 ekind_capName (old->ukind),
6961 uentry_getName (unew),
6962 ekind_unparseLong (unew->ukind)),
6963 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
6965 uentry_showWhereLastKind (old);
6971 uentry_updateInto (old, unew);
6975 ** def is the definition of spec, modifies spec
6977 ** reports any inconsistencies
6978 ** returns the summary of all available information
6979 ** if spec and def are inconsistent, def is returned
6983 uentry_showWhereLast (uentry spec)
6985 if (uentry_isValid (spec))
6987 if (fileloc_isDefined (spec->whereDefined)
6988 && !fileloc_isLib (spec->whereDefined)
6989 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6991 llgenindentmsg (message ("Previous definition of %q: %t",
6992 uentry_getName (spec),
6993 uentry_getType (spec)),
6994 uentry_whereDefined (spec));
6996 else if (uentry_isDeclared (spec))
6998 llgenindentmsg (message ("Previous declaration of %q: %t",
6999 uentry_getName (spec),
7000 uentry_getType (spec)),
7001 uentry_whereDeclared (spec));
7003 else if (uentry_isSpecified (spec))
7005 if (uentry_hasName (spec))
7007 llgenindentmsg (message ("Specification of %q: %t",
7008 uentry_getName (spec),
7009 uentry_getType (spec)),
7010 uentry_whereSpecified (spec));
7014 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
7015 uentry_whereSpecified (spec));
7020 /* nothing to show */
7026 uentry_showWhereLastKind (uentry spec)
7028 if (uentry_isValid (spec))
7030 if (fileloc_isDefined (spec->whereDefined)
7031 && !fileloc_isLib (spec->whereDefined)
7032 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
7034 llgenindentmsg (message ("Previous definition of %q as %s: %t",
7035 uentry_getName (spec),
7036 ekind_unparseLong (spec->ukind),
7037 uentry_getType (spec)),
7038 uentry_whereDefined (spec));
7040 else if (uentry_isDeclared (spec))
7042 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
7043 uentry_getName (spec),
7044 ekind_unparseLong (spec->ukind),
7045 uentry_getType (spec)),
7046 uentry_whereDeclared (spec));
7048 else if (uentry_isSpecified (spec))
7050 if (uentry_hasName (spec))
7052 llgenindentmsg (message ("Specification of %q as %s: %t",
7053 uentry_getName (spec),
7054 ekind_unparseLong (spec->ukind),
7055 uentry_getType (spec)),
7056 uentry_whereSpecified (spec));
7060 llgenindentmsg (message ("Specification as %s: %t",
7061 ekind_unparseLong (spec->ukind),
7062 uentry_getType (spec)),
7063 uentry_whereSpecified (spec));
7068 /* nothing to show */
7074 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
7076 fileloc loc = uentry_whereDefined (ce);
7078 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7080 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7084 loc = uentry_whereSpecified (ce);
7086 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7088 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7093 void uentry_showWhereLastExtra (uentry spec, cstring extra)
7095 if (uentry_isDeclared (spec))
7097 llgenindentmsg (message ("Previous declaration of %q: %q",
7098 uentry_getName (spec), extra),
7099 uentry_whereDeclared (spec));
7101 else if (uentry_isSpecified (spec))
7103 llgenindentmsg (message ("Specification of %q: %q",
7104 uentry_getName (spec), extra),
7105 uentry_whereSpecified (spec));
7109 cstring_free (extra);
7114 uentry_showWhereDeclared (uentry spec)
7116 if (uentry_isDeclared (spec))
7118 if (uentry_hasName (spec))
7120 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7121 uentry_whereDeclared (spec));
7125 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7128 else if (uentry_isSpecified (spec))
7130 if (uentry_hasName (spec))
7132 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7133 uentry_whereSpecified (spec));
7137 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7142 /* nothing to show */
7148 uentry_showWhereAny (uentry spec)
7150 if (uentry_isDeclared (spec))
7152 if (uentry_hasName (spec))
7154 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7155 uentry_whereDeclared (spec));
7159 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7162 else if (uentry_isSpecified (spec))
7164 if (uentry_hasName (spec))
7166 llgenindentmsg (message ("Specification of %q",
7167 uentry_getName (spec)),
7168 uentry_whereSpecified (spec));
7172 llgenindentmsg (cstring_makeLiteral ("Specification"),
7173 uentry_whereSpecified (spec));
7176 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7178 if (uentry_hasName (spec))
7180 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7181 uentry_whereDefined (spec));
7185 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7190 /* nothing to show */
7195 uentry_showWhereDefined (uentry spec)
7197 if (uentry_isCodeDefined (spec))
7199 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7200 uentry_whereDefined (spec));
7205 uentry_showWhereLastPlain (uentry spec)
7207 if (uentry_isDeclared (spec))
7209 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7210 uentry_whereDeclared (spec));
7212 else if (uentry_isSpecified (spec))
7214 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7215 uentry_whereSpecified (spec));
7223 uentry_showWhereLastVal (uentry spec, cstring val)
7225 if (uentry_isDeclared (spec))
7227 llgenindentmsg (message ("Previous declaration of %q: %s",
7228 uentry_getName (spec), val),
7229 uentry_whereDeclared (spec));
7231 else if (uentry_isSpecified (spec))
7233 llgenindentmsg (message ("Specification of %q: %s",
7234 uentry_getName (spec), val),
7235 uentry_whereSpecified (spec));
7243 uentry_showWhereSpecified (uentry spec)
7245 if (uentry_isSpecified (spec))
7247 if (uentry_hasName (spec))
7249 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7250 uentry_whereSpecified (spec));
7254 llgenindentmsg (cstring_makeLiteral ("Specification"),
7255 uentry_whereSpecified (spec));
7258 else if (uentry_isDeclared (spec))
7260 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7261 uentry_whereDeclared (spec));
7265 /* nothing to show */
7270 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7272 if (uentry_isSpecified (spec))
7274 if (uentry_hasName (spec))
7276 llgenindentmsg (message ("Specification of %q: %q",
7277 uentry_getName (spec), s),
7278 uentry_whereSpecified (spec));
7282 llgenindentmsg (message ("Specification: %q", s),
7283 uentry_whereSpecified (spec));
7286 else if (uentry_isDeclared (spec))
7288 llgenindentmsg (message ("Declaration of %q: %q",
7289 uentry_getName (spec), s),
7290 uentry_whereDeclared (spec));
7294 llgenindentmsg (message ("Previous: %q", s),
7295 uentry_whereLast (spec));
7304 checkStructConformance (uentry old, uentry unew)
7307 uentryList fold, fnew;
7310 ** requires: types of old and new are structs or unions
7313 llassert (uentry_isValid (old));
7314 llassert (uentry_isValid (unew));
7316 oldr = ctype_realType (old->utype);
7317 fold = ctype_getFields (oldr);
7319 newr = ctype_realType (unew->utype);
7320 fnew = ctype_getFields (newr);
7322 if (!uentryList_matchFields (fold, fnew))
7324 if (fileloc_equal (uentry_whereLast (old),
7325 uentry_whereLast (unew)))
7333 message ("%q %q %rdeclared with fields { %q }, %s "
7334 "with fields { %q }",
7335 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7336 uentry_getName (old),
7337 uentry_isDeclared (old),
7338 uentryList_unparseAbbrev (fnew),
7339 uentry_specOrDefName (old),
7340 uentryList_unparseAbbrev (fold)),
7341 uentry_whereDeclared (unew)))
7343 uentry_showWhereLastPlain (old);
7344 uentryList_showFieldDifference (fold, fnew);
7348 old->utype = unew->utype;
7353 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7356 ** requires old and new are enums
7359 ctype rold = ctype_realType (old->utype);
7360 ctype rnew = ctype_realType (unew->utype);
7361 enumNameList eold = ctype_elist (rold);
7362 enumNameList enew = ctype_elist (rnew);
7364 if (!enumNameList_match (eold, enew))
7368 message ("Enum %q declared with members { %q } but "
7369 "%s with members { %q }",
7370 uentry_getName (old),
7371 enumNameList_unparse (enew),
7372 uentry_specOrDefName (old),
7373 enumNameList_unparse (eold)),
7374 uentry_whereDeclared (unew)))
7376 uentry_showWhereSpecified (old);
7377 old->utype = unew->utype;
7383 ** either oldCurrent or newCurrent may be undefined!
7387 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7388 uentry unew, uentry newCurrent, ctype newType,
7391 bool hasError = FALSE;
7393 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7395 if (uentry_hasName (newCurrent))
7397 hasError = optgenerror
7399 message ("Parameter %d, %q, of function %q has inconsistent type: "
7400 "declared %t, %s %t",
7401 paramno + 1, uentry_getName (newCurrent),
7402 uentry_getName (unew),
7403 newType, uentry_specOrDefName (old), oldType),
7404 uentry_whereDeclared (newCurrent));
7408 hasError = optgenerror
7410 message ("Parameter %d of function %q has inconsistent type: "
7411 "declared %t, %s %t",
7412 paramno + 1, uentry_getName (unew),
7413 newType, uentry_specOrDefName (old), oldType),
7414 uentry_whereDeclared (newCurrent));
7416 DPRINTF (("type: %s / %s",
7417 ctype_unparse (newType),
7418 ctype_unparse (ctype_realType (newType))));
7423 if (uentry_isDeclared (unew))
7425 hasError = optgenerror
7427 message ("Parameter %d of function %s has inconsistent type: "
7428 "declared %t, %s %t",
7429 paramno + 1, unew->uname,
7430 newType, uentry_specOrDefName (old), oldType),
7431 uentry_whereDeclared (unew));
7435 hasError = optgenerror
7437 message ("Parameter %d of function %s has inconsistent type: "
7438 "declared %t, %s %t",
7439 paramno + 1, unew->uname,
7440 newType, uentry_specOrDefName (old), oldType),
7441 uentry_whereDeclared (unew));
7447 DPRINTF (("Here: %s / %s",
7448 uentry_unparseFull (oldCurrent),
7449 uentry_unparseFull (newCurrent)));
7451 if (!uentry_isUndefined (oldCurrent))
7453 if (!uentry_isUndefined (newCurrent)
7454 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7456 uentry_showWhereLast (oldCurrent);
7460 uentry_showWhereLastPlain (old);
7463 uentry_setType (oldCurrent, newType);
7467 uentry_showWhereLastPlain (old);
7473 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7477 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7479 uentry_isDeclared (old),
7480 uentryList_size (uentry_getParams (unew)),
7481 uentry_specOrDefName (old),
7482 uentryList_size (uentry_getParams (old))),
7483 uentry_whereDeclared (unew)))
7485 uentry_showWhereLastPlain (old);
7490 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7494 message ("Function %s inconsistently %rdeclared to return %t",
7496 uentry_isDeclared (old),
7497 ctype_getReturnType (unew->utype)),
7498 uentry_whereDeclared (unew)))
7500 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7504 static cstring paramStorageName (uentry ue)
7506 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7509 static cstring fcnErrName (uentry ue)
7511 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7514 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7516 if (uentry_isVar (ue))
7518 return (checkedName (ue->info->var->checked));
7522 return (cstring_makeLiteralTemp ("<checked invalid>"));
7526 static cstring checkedName (chkind checked)
7530 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7531 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7532 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7533 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7534 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7540 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7545 if (uentry_isVar (unew))
7547 llassert (uentry_isVar (old));
7549 oldState = old->info->var->nullstate;
7550 newState = unew->info->var->nullstate;
7554 oldState = sRef_getNullState (old->sref);
7555 newState = sRef_getNullState (unew->sref);
7558 if (oldState == NS_ABSNULL)
7560 if (uentry_isVar (old))
7562 old->info->var->nullstate = newState;
7565 sRef_mergeNullState (old->sref, newState);
7567 else if (newState == NS_UNKNOWN)
7569 if (completeConform && newState != oldState
7570 && uentry_isReallySpecified (old))
7574 message ("%s %q specified as %s, but declared without %s qualifier",
7575 ekind_capName (unew->ukind),
7576 uentry_getName (unew),
7577 nstate_unparse (oldState),
7578 nstate_unparse (oldState)),
7579 uentry_whereDeclared (unew)))
7581 uentry_showWhereSpecified (old);
7585 if (uentry_isVar (unew))
7587 unew->info->var->nullstate = oldState;
7590 sRef_mergeNullState (unew->sref, oldState);
7592 else if (newState == NS_POSNULL)
7594 if (oldState == NS_MNOTNULL
7595 && (ctype_isUA (unew->utype)
7596 || (uentry_isFunction (unew)
7597 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7599 if (uentry_isVar (unew))
7601 unew->info->var->nullstate = oldState;
7604 sRef_mergeNullState (unew->sref, oldState);
7608 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7609 || oldState == NS_UNKNOWN)
7616 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7618 uentry_ekindName (unew),
7619 uentry_getName (unew),
7620 uentry_isDeclared (old),
7622 uentry_specOrDefName (old),
7623 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7624 uentry_whereDeclared (unew)))
7626 uentry_showWhereSpecified (old);
7631 if (uentry_isVar (old))
7633 old->info->var->nullstate = newState;
7636 sRef_mergeNullState (old->sref, newState);
7639 else if (newState == NS_MNOTNULL)
7641 if (oldState != NS_MNOTNULL)
7647 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7648 "%s without notnull qualifier",
7649 uentry_ekindName (unew),
7650 uentry_getName (unew),
7651 uentry_isDeclared (old),
7653 uentry_specOrDefName (old)),
7654 uentry_whereDeclared (unew)))
7656 uentry_showWhereSpecified (old);
7660 if (uentry_isVar (old))
7662 old->info->var->nullstate = newState;
7665 sRef_mergeNullState (old->sref, newState);
7670 if (uentry_isVar (unew))
7672 unew->info->var->nullstate = oldState;
7675 sRef_mergeNullState (unew->sref, oldState);
7680 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7681 bool mustConform, bool completeConform)
7687 if (uentry_isVar (old) && uentry_isVar (unew))
7689 oldState = old->info->var->defstate;
7690 newState = unew->info->var->defstate;
7695 oldState = sRef_getDefState (old->sref);
7696 newState = sRef_getDefState (unew->sref);
7699 if (newState != oldState
7700 && newState != SS_UNKNOWN
7701 && newState != SS_DEFINED)
7707 message ("%s %q inconsistently %rdeclared %s %s %s, "
7709 uentry_ekindName (unew),
7710 uentry_getName (unew),
7711 uentry_isDeclared (old),
7713 sstate_unparse (newState),
7714 paramStorageName (unew),
7715 uentry_specOrDefName (old),
7717 sstate_unparse (oldState),
7718 paramStorageName (unew)),
7719 uentry_whereDeclared (unew)))
7721 uentry_showWhereSpecified (old);
7725 if (vars) old->info->var->defstate = newState;
7726 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7731 && (newState != oldState) && (oldState != SS_DEFINED)
7732 && uentry_isReallySpecified (old))
7736 message ("%s %q specified as %s, but declared without %s qualifier",
7737 ekind_capName (unew->ukind),
7738 uentry_getName (unew),
7739 sstate_unparse (oldState),
7740 sstate_unparse (oldState)),
7741 uentry_whereDeclared (unew)))
7743 uentry_showWhereSpecified (old);
7747 if (vars) unew->info->var->defstate = oldState;
7748 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7753 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7754 bool mustConform, bool completeConform)
7759 oldKind = sRef_getAliasKind (old->sref);
7760 newKind = sRef_getAliasKind (unew->sref);
7762 if (alkind_isImplicit (newKind)
7763 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7765 if (completeConform && !alkind_equal (newKind, oldKind)
7766 && uentry_isReallySpecified (old))
7770 message ("%s %q specified as %s, but declared without "
7771 "explicit alias qualifier",
7772 ekind_capName (unew->ukind),
7773 uentry_getName (unew),
7774 alkind_unparse (oldKind)),
7775 uentry_whereDeclared (unew)))
7777 uentry_showWhereSpecified (old);
7782 ** This really shouldn't be necessary, but it is!
7783 ** Function params (?) use new here.
7786 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7790 if (alkind_isKnown (newKind))
7792 if (!alkind_equal (oldKind, newKind))
7794 if (alkind_isKnown (oldKind))
7799 message ("%s %q inconsistently %rdeclared %s %s storage, "
7801 uentry_ekindName (unew),
7802 uentry_getName (unew),
7803 uentry_isDeclared (old),
7805 alkind_unparse (newKind),
7806 uentry_specOrDefName (old),
7807 alkind_unparse (oldKind)),
7808 uentry_whereDeclared (unew)))
7810 uentry_showWhereSpecified (old);
7812 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7813 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7814 sRef_setAliasKind (old->sref, AK_ERROR,
7815 uentry_whereDeclared (unew));
7819 sRef_setAliasKind (old->sref, newKind,
7820 uentry_whereDeclared (unew));
7825 if (!(alkind_isImplicit (newKind)))
7828 !uentry_isFunction (unew) &&
7831 message ("%s %q inconsistently %rdeclared %s %s storage, "
7832 "implicitly %s as temp storage",
7833 uentry_ekindName (unew),
7834 uentry_getName (unew),
7835 uentry_isDeclared (old),
7837 alkind_unparse (newKind),
7838 uentry_specOrDefName (old)),
7839 uentry_whereDeclared (unew)))
7841 uentry_showWhereSpecified (old);
7845 sRef_setAliasKind (old->sref, newKind,
7846 uentry_whereDeclared (unew));
7848 else /* newKind is temp or refcounted */
7855 else /* newKind unknown */
7862 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7863 bool mustConform, bool completeConform)
7868 oldKind = sRef_getExKind (old->sref);
7869 newKind = sRef_getExKind (unew->sref);
7871 if (exkind_isKnown (newKind))
7873 if (oldKind != newKind)
7875 if (exkind_isKnown (oldKind))
7880 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7881 uentry_ekindName (unew),
7882 uentry_getName (unew),
7883 uentry_isDeclared (old),
7885 exkind_unparse (newKind),
7886 uentry_specOrDefName (old),
7887 exkind_unparse (oldKind)),
7888 uentry_whereDeclared (unew)))
7890 uentry_showWhereSpecified (old);
7893 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7900 message ("%s %q inconsistently %rdeclared %s %s, "
7901 "implicitly %s without exposure qualifier",
7902 uentry_ekindName (unew),
7903 uentry_getName (unew),
7904 uentry_isDeclared (old),
7906 exkind_unparse (newKind),
7907 uentry_specOrDefName (old)),
7908 uentry_whereDeclared (unew)))
7910 uentry_showWhereSpecified (old);
7913 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7919 if (completeConform && exkind_isKnown (oldKind)
7920 && uentry_isReallySpecified (old))
7924 message ("%s %q specified as %s, but declared without "
7925 "exposure qualifier",
7926 ekind_capName (unew->ukind),
7927 uentry_getName (unew),
7928 exkind_unparse (oldKind)),
7929 uentry_whereDeclared (unew)))
7931 uentry_showWhereSpecified (old);
7935 /* yes, this is necessary! (if its a param) */
7936 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7941 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7942 bool mustConform, /*@unused@*/ bool completeConform)
7944 valueTable newvals = sRef_getValueTable (unew->sref);
7946 if (valueTable_isDefined (newvals))
7948 DPRINTF (("Check meta state: %s -> %s",
7949 uentry_unparseFull (old),
7950 uentry_unparseFull (unew)));
7952 DPRINTF (("Check meta state refs: %s -> %s",
7953 sRef_unparseFull (old->sref),
7954 sRef_unparseFull (unew->sref)));
7956 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7959 ** Copy the new values into the old ref
7962 valueTable_elements (newvals, key, newval)
7964 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7965 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7967 llassert (metaStateInfo_isDefined (msinfo));
7969 if (stateValue_isUndefined (oldval))
7971 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7975 if (stateValue_isError (oldval))
7977 if (!stateValue_isError (newval))
7979 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7983 ; /* No change necessary. */
7988 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7990 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7996 if (!stateValue_isError (newval)
7997 && !stateValue_isImplicit (newval))
7999 if (uentry_hasName (unew)
8000 || !sRef_isParam (uentry_getSref (unew)))
8005 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
8006 uentry_ekindName (unew),
8007 uentry_getName (unew),
8008 uentry_isDeclared (old),
8010 stateValue_unparseValue (newval, msinfo),
8011 uentry_specOrDefName (old),
8012 stateValue_unparseValue (oldval, msinfo)),
8013 uentry_whereDeclared (unew)))
8015 uentry_showWhereSpecified (old);
8023 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
8024 uentry_ekindName (unew),
8025 sRef_getParam (uentry_getSref (unew)),
8026 uentry_isDeclared (old),
8028 stateValue_unparseValue (newval, msinfo),
8029 uentry_specOrDefName (old),
8030 stateValue_unparseValue (oldval, msinfo)),
8031 uentry_whereDeclared (unew)))
8033 uentry_showWhereSpecified (old);
8039 DPRINTF (("Updating!"));
8040 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
8044 DPRINTF (("Values match"));
8048 } end_valueTable_elements ;
8053 uentry_checkStateConformance (/*@notnull@*/ uentry old,
8054 /*@notnull@*/ uentry unew,
8055 bool mustConform, bool completeConform)
8057 checkDefState (old, unew, mustConform, completeConform);
8058 checkNullState (old, unew, mustConform, completeConform);
8059 checkAliasState (old, unew, mustConform, completeConform);
8060 checkExpState (old, unew, mustConform, completeConform);
8061 checkMetaState (old, unew, mustConform, completeConform);
8063 sRef_storeState (old->sref);
8064 sRef_storeState (unew->sref);
8068 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
8070 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
8075 llassert (uentry_isVar (old));
8076 llassert (uentry_isVar (unew));
8078 if (cstring_isEmpty (old->uname))
8080 cstring_free (old->uname);
8081 old->uname = cstring_copy (unew->uname);
8084 if (unew->info->var->kind == VKRETPARAM
8085 || unew->info->var->kind == VKSEFRETPARAM)
8087 if (old->info->var->kind != VKRETPARAM
8088 && old->info->var->kind != VKSEFRETPARAM)
8092 message ("Parameter %q inconsistently %rdeclared as "
8093 "returned parameter",
8094 uentry_getName (unew),
8095 uentry_isDeclared (old)),
8096 uentry_whereDeclared (unew)))
8098 uentry_showWhereSpecified (old);
8099 old->info->var->kind = unew->info->var->kind;
8105 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8107 if (old->info->var->kind != VKSEFPARAM
8108 && old->info->var->kind != VKSEFRETPARAM)
8112 message ("Parameter %qinconsistently %rdeclared as "
8114 uentry_getOptName (unew),
8115 uentry_isDeclared (old)),
8116 uentry_whereDeclared (unew)))
8118 uentry_showWhereSpecified (old);
8119 old->info->var->kind = unew->info->var->kind;
8124 if (old->info->var->kind == VKSPEC)
8126 old->info->var->kind = unew->info->var->kind;
8130 unew->info->var->kind = old->info->var->kind;
8133 if (unew->info->var->checked != CH_UNKNOWN
8134 && unew->info->var->checked != old->info->var->checked)
8136 if (old->info->var->checked == CH_UNKNOWN
8137 && !fileloc_isUser (uentry_whereLast (old)))
8145 message ("Variable %q inconsistently %rdeclared as "
8146 "%s parameter (was %s)",
8147 uentry_getName (unew),
8148 uentry_isDeclared (old),
8149 checkedName (unew->info->var->checked),
8150 checkedName (old->info->var->checked)),
8151 uentry_whereDeclared (unew)))
8153 uentry_showWhereSpecified (old);
8157 old->info->var->checked = unew->info->var->checked;
8162 && (old->info->var->checked != CH_UNKNOWN)
8163 && uentry_isReallySpecified (old))
8167 message ("%s %q specified as %s, but declared without %s qualifier",
8168 ekind_capName (unew->ukind),
8169 uentry_getName (unew),
8170 checkedName (old->info->var->checked),
8171 checkedName (old->info->var->checked)),
8172 uentry_whereDeclared (unew)))
8174 uentry_showWhereSpecified (old);
8178 unew->info->var->checked = old->info->var->checked;
8181 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8184 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8186 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8191 llassert (uentry_isVar (u1));
8192 llassert (uentry_isVar (u2));
8194 if (u1->info->var->kind != u2->info->var->kind) {
8195 if (u1->info->var->kind == VKSEFRETPARAM) {
8196 if (u2->info->var->kind == VKRETPARAM) {
8199 message ("Function types are inconsistent. Parameter %d is "
8200 "sef parameter, but non-sef parameter in "
8201 "assigned function: %s",
8202 paramno, exprNode_unparse (e)),
8204 } else if (u2->info->var->kind == VKSEFPARAM) {
8207 message ("Function types are inconsistent. Parameter %d is "
8208 "returns parameter, but non-returns parameter in "
8209 "assigned function: %s",
8210 paramno, exprNode_unparse (e)),
8215 message ("Function types are inconsistent. Parameter %d is "
8216 "sef returns parameter, but non-sef returns parameter in "
8217 "assigned function: %s",
8218 paramno, exprNode_unparse (e)),
8221 } else if (u1->info->var->kind == VKRETPARAM) {
8224 message ("Function types are inconsistent. Parameter %d is "
8225 "returns parameter, but non-returns parameter in "
8226 "assigned function: %s",
8227 paramno, exprNode_unparse (e)),
8229 } else if (u1->info->var->kind == VKSEFPARAM) {
8232 message ("Function types are inconsistent. Parameter %d is "
8233 "sef parameter, but non-sef parameter in "
8234 "assigned function: %s",
8235 paramno, exprNode_unparse (e)),
8238 if (u2->info->var->kind == VKSEFRETPARAM) {
8241 message ("Function types are inconsistent. Parameter %d is "
8242 "normal parameter, but sef returns parameter in "
8243 "assigned function: %s",
8244 paramno, exprNode_unparse (e)),
8246 } else if (u2->info->var->kind == VKSEFPARAM) {
8249 message ("Function types are inconsistent. Parameter %d is "
8250 "normal parameter, but sef parameter in "
8251 "assigned function: %s",
8252 paramno, exprNode_unparse (e)),
8254 } else if (u2->info->var->kind == VKRETPARAM) {
8257 message ("Function types are inconsistent. Parameter %d is "
8258 "normal parameter, but returns parameter in "
8259 "assigned function: %s",
8260 paramno, exprNode_unparse (e)),
8268 if (u1->info->var->defstate != u2->info->var->defstate)
8272 message ("Function types are inconsistent. Parameter %d is "
8273 "%s, but %s in assigned function: %s",
8275 sstate_unparse (u1->info->var->defstate),
8276 sstate_unparse (u2->info->var->defstate),
8277 exprNode_unparse (e)),
8281 if (u1->info->var->nullstate != u2->info->var->nullstate)
8285 message ("Function types are inconsistent. Parameter %d is "
8286 "%s, but %s in assigned function: %s",
8288 nstate_unparse (u1->info->var->nullstate),
8289 nstate_unparse (u2->info->var->nullstate),
8290 exprNode_unparse (e)),
8294 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8298 message ("Function types are inconsistent. Parameter %d is "
8299 "%s, but %s in assigned function: %s",
8301 alkind_unparse (sRef_getAliasKind (u1->sref)),
8302 alkind_unparse (sRef_getAliasKind (u2->sref)),
8303 exprNode_unparse (e)),
8307 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8311 message ("Function types are inconsistent. Parameter %d is "
8312 "%s, but %s in assigned function: %s",
8314 exkind_unparse (sRef_getExKind (u1->sref)),
8315 exkind_unparse (sRef_getExKind (u2->sref)),
8316 exprNode_unparse (e)),
8321 static void uentry_convertIntoFunction (/*@notnull@*/ uentry old)
8324 ** Convert old into a function
8328 old->utype = ctype_unknown;
8329 old->info->fcn = (ufinfo) dmalloc (sizeof (*old->info->fcn));
8330 old->info->fcn->hasMods = FALSE;
8331 old->info->fcn->hasGlobs = FALSE;
8332 old->info->fcn->exitCode = XK_UNKNOWN;
8333 old->info->fcn->nullPred = qual_createUnknown ();
8334 old->info->fcn->specialCode = SPC_NONE;
8335 old->info->fcn->access = typeIdSet_undefined;
8336 old->info->fcn->globs = globSet_undefined;
8337 old->info->fcn->defparams = uentryList_undefined;
8338 old->info->fcn->mods = sRefSet_undefined;
8339 old->info->fcn->specclauses = NULL;
8340 old->info->fcn->preconditions = NULL;
8341 old->info->fcn->postconditions = NULL;
8345 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8346 /*@notnull@*/ uentry unew,
8347 bool mustConform, /*@unused@*/ bool completeConform)
8349 uentryList oldParams = uentry_getParams (old);
8350 uentryList newParams = uentry_getParams (unew);
8351 ctype newType = unew->utype;
8352 ctype oldType = ctype_realType (old->utype);
8353 ctype oldRetType = ctype_unknown;
8354 ctype newRetType = ctype_unknown;
8356 DPRINTF (("Function conform: %s ==> %s",
8357 uentry_unparseFull (old),
8358 uentry_unparseFull (unew)));
8360 if (uentry_isForward (old))
8362 mustConform = FALSE;
8363 uentry_updateInto (old, unew);
8368 ** check return values
8371 if (ctype_isKnown (oldType))
8373 if (ctype_isFunction (oldType))
8375 oldRetType = ctype_getReturnType (oldType);
8381 message ("%s %q declared as function, but previously declared as %s",
8382 ekind_capName (unew->ukind),
8383 uentry_getName (unew),
8384 ekind_unparseLong (old->ukind)),
8385 uentry_whereDeclared (unew)))
8387 uentry_showWhereLast (old);
8390 uentry_convertIntoFunction (old);
8395 if (ctype_isKnown (newType))
8397 llassert (ctype_isFunction (newType));
8398 newRetType = ctype_getReturnType (newType);
8401 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8402 && !ctype_matchDef (newRetType, oldRetType))
8404 if (mustConform) returnValueError (old, unew);
8408 if (ctype_isConj (newRetType))
8410 if (ctype_isConj (oldRetType))
8412 if (!ctype_sameAltTypes (newRetType, oldRetType))
8416 message ("Function %q inconsistently %rdeclared to "
8417 "return alternate types %s "
8418 "(types match, but alternates are not identical, "
8419 "so checking may not be correct)",
8420 uentry_getName (unew),
8421 uentry_isDeclared (old),
8422 ctype_unparse (newRetType)),
8423 uentry_whereDeclared (unew)))
8425 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8431 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8436 DPRINTF (("Before state: %s",
8437 uentry_unparseFull (old)));
8438 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8439 DPRINTF (("After state: %s",
8440 uentry_unparseFull (old)));
8442 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8444 if (exitkind_isKnown (unew->info->fcn->exitCode))
8448 message ("Function %q inconsistently %rdeclared using %s",
8449 uentry_getName (unew),
8450 uentry_isDeclared (old),
8451 exitkind_unparse (unew->info->fcn->exitCode)),
8452 uentry_whereDeclared (unew)))
8454 uentry_showWhereSpecified (old);
8459 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8463 if (!qual_isUnknown (unew->info->fcn->nullPred))
8465 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8469 message ("Function %q inconsistently %rdeclared using %s",
8470 uentry_getName (unew),
8471 uentry_isDeclared (old),
8472 qual_unparse (unew->info->fcn->nullPred)),
8473 uentry_whereDeclared (unew)))
8475 uentry_showWhereSpecified (old);
8481 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8484 if (unew->info->fcn->specialCode != SPC_NONE)
8486 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8490 message ("Function %q inconsistently %rdeclared using %s",
8491 uentry_getName (unew),
8492 uentry_isDeclared (old),
8493 specCode_unparse (unew->info->fcn->specialCode)),
8494 uentry_whereDeclared (unew)))
8496 uentry_showWhereSpecified (old);
8502 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8509 if (!uentryList_sameObject (oldParams, newParams)
8510 && (!uentryList_isMissingParams (oldParams)))
8512 if (!uentryList_isMissingParams (newParams))
8515 int nparams = uentryList_size (oldParams);
8516 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8518 if (nparams != uentryList_size (newParams))
8520 nargsError (old, unew);
8523 if (uentryList_size (newParams) < nparams)
8525 nparams = uentryList_size (newParams);
8528 while (paramno < nparams)
8530 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8531 uentry newCurrent = uentryList_getN (newParams, paramno);
8532 ctype oldCurrentType = uentry_getType (oldCurrent);
8533 ctype newCurrentType = uentry_getType (newCurrent);
8535 llassert (uentry_isValid (oldCurrent)
8536 && uentry_isValid (newCurrent));
8538 if (!uentry_isElipsisMarker (oldCurrent)
8539 && !uentry_isElipsisMarker (newCurrent))
8541 checkVarConformance (oldCurrent, newCurrent,
8542 mustConform, completeConform);
8547 if (uentry_hasName (oldCurrent)
8548 && uentry_hasName (newCurrent))
8550 cstring oldname = uentry_getName (oldCurrent);
8551 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8553 cstring nname = uentry_getName (newCurrent);
8556 if (cstring_isDefined (pfx)
8557 && cstring_equalPrefix (oldname, pfx))
8559 oname = cstring_suffix (oldname, cstring_length (pfx));
8564 /*@-branchstate@*/ } /*@=branchstate@*/
8566 if (cstring_isDefined (pfx)
8567 && cstring_equalPrefix (nname, pfx))
8569 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8574 /*@-branchstate@*/ } /*@=branchstate@*/
8576 if (!cstring_equal (oname, nnamefix))
8579 (FLG_DECLPARAMMATCH,
8580 message ("Definition parameter name %s does not match "
8581 "name of corresponding parameter in "
8584 uentry_whereLast (newCurrent)))
8586 uentry_showWhereLastPlain (oldCurrent);
8590 cstring_free (oldname);
8591 cstring_free (nname);
8595 if (!ctype_match (oldCurrentType, newCurrentType))
8597 paramTypeError (old, oldCurrent, oldCurrentType,
8598 unew, newCurrent, newCurrentType, paramno);
8602 if (ctype_isMissingParamsMarker (newCurrentType)
8603 || ctype_isElips (newCurrentType)
8604 || ctype_isMissingParamsMarker (oldCurrentType)
8605 || ctype_isElips (oldCurrentType))
8611 if (ctype_isConj (newCurrentType))
8613 if (ctype_isConj (oldCurrentType))
8615 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8619 message ("Parameter %q inconsistently %rdeclared with "
8620 "alternate types %s "
8621 "(types match, but alternates are not identical, "
8622 "so checking may not be correct)",
8623 uentry_getName (newCurrent),
8624 uentry_isDeclared (oldCurrent),
8625 ctype_unparse (newCurrentType)),
8626 uentry_whereDeclared (unew)))
8628 uentry_showWhereLastVal (oldCurrent,
8629 ctype_unparse (oldCurrentType));
8637 message ("Parameter %q inconsistently %rdeclared with "
8638 "alternate types %s",
8639 uentry_getName (newCurrent),
8640 uentry_isDeclared (oldCurrent),
8641 ctype_unparse (newCurrentType)),
8642 uentry_whereDeclared (unew)))
8644 uentry_showWhereLastVal (oldCurrent,
8645 ctype_unparse (oldCurrentType));
8652 if (ctype_isConj (oldCurrentType))
8654 uentry_setType (newCurrent, oldCurrentType);
8662 ** Forgot this! detected by splint:
8663 ** uentry.c:1257,15: Suspected infinite loop
8669 if (!uentryList_isMissingParams (newParams))
8671 if (ctype_isConj (oldRetType))
8673 old->utype = ctype_makeFunction (oldRetType,
8674 uentryList_copy (newParams));
8678 old->utype = unew->utype;
8682 checkGlobalsConformance (old, unew, mustConform, completeConform);
8683 checkModifiesConformance (old, unew, mustConform, completeConform);
8685 DPRINTF (("Before list: %s",
8686 uentry_unparseFull (old)));
8688 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8690 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8695 message ("Function %q redeclared using special clauses (can only "
8696 "be used in first declaration)",
8697 uentry_getName (unew)),
8698 uentry_whereDeclared (unew)))
8700 uentry_showWhereLast (old);
8704 /* need to add some checking @*/
8705 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8709 /* should be able to append? */
8711 stateClauseList_checkEqual (old, unew);
8712 stateClauseList_free (unew->info->fcn->specclauses);
8713 unew->info->fcn->specclauses = stateClauseList_undefined;
8717 /*@=branchstate@*/ /* shouldn't need this */
8719 if (fileloc_isUndefined (old->whereDeclared))
8721 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8723 else if (fileloc_isUndefined (unew->whereDeclared))
8725 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8732 } /*@=compmempass@*/ /* I think this is a spurious warning */
8735 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8739 llassert (uentry_isValid (ue));
8740 llassert (uentry_isEitherConstant (ue));
8742 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8743 uval = uentry_getConstantValue (ue);
8745 if (multiVal_isDefined (uval))
8747 if (multiVal_isDefined (m))
8749 if (!multiVal_equiv (uval, m))
8753 message ("%s %q defined with inconsistent value: %q",
8754 ekind_capName (ue->ukind),
8755 uentry_getName (ue),
8756 multiVal_unparse (m)),
8759 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8767 uentry_setConstantValue (ue, m);
8772 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8775 bool typeError = FALSE;
8777 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8779 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8783 DPRINTF (("Check struct conformance: %s / %s",
8784 uentry_unparseFull (old),
8785 uentry_unparseFull (unew)));
8786 checkStructConformance (old, unew);
8791 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8793 llbug (message ("struct tags: bad types: %t / %t",
8794 old->utype, unew->utype));
8798 else if (uentry_isEnumTag (old))
8800 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8802 if (mustConform) checkEnumConformance (old, unew);
8806 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8808 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8809 ctype_unparse (unew->utype)));
8813 else if (!ctype_match (old->utype, unew->utype))
8815 DPRINTF (("Type mismatch: %s / %s",
8816 ctype_unparse (old->utype),
8817 ctype_unparse (unew->utype)));
8819 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8821 ctype realt = ctype_realType (unew->utype);
8823 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8825 unew->utype = ctype_bool;
8831 typeError = optgenerror
8833 message ("%q defined as %s", uentry_getName (old),
8834 ctype_unparse (realt)),
8835 uentry_whereDeclared (unew));
8843 ctype oldr = ctype_realType (old->utype);
8844 ctype newr = ctype_realType (unew->utype);
8846 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8848 checkStructConformance (old, unew);
8850 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8852 checkStructConformance (old, unew);
8854 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8856 checkEnumConformance (old, unew);
8858 else if (uentry_isConstant (old)
8859 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8861 /* okay...for now! (should check the type is reset later... */
8865 DPRINTF (("YABA!"));
8868 message ("%s %q %rdeclared with inconsistent type: %t",
8869 ekind_capName (unew->ukind),
8870 uentry_getName (unew),
8871 uentry_isDeclared (old),
8873 uentry_whereDeclared (unew)))
8875 uentry_showWhereLast (old);
8891 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8892 /*@notnull@*/ uentry unew,
8893 bool mustConform, bool completeConform)
8895 if (ctype_isDefined (unew->info->datatype->type))
8898 ** bool is hard coded here, since it is built into LCL.
8899 ** For now, we're stuck with LCL's types.
8902 if (ctype_isDirectBool (old->utype) &&
8903 cstring_equalLit (unew->uname, "bool"))
8905 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8906 evs 2000-07-25: removed
8908 unew->utype = ctype_bool;
8911 if (ctype_isUnknown (old->info->datatype->type))
8913 old->info->datatype->type = unew->info->datatype->type;
8917 DPRINTF (("Old: %s / New: %s",
8918 uentry_unparseFull (old),
8919 uentry_unparseFull (unew)));
8920 DPRINTF (("Types: %s / %s",
8921 ctype_unparse (old->info->datatype->type),
8922 ctype_unparse (unew->info->datatype->type)));
8924 if (ctype_matchDef (old->info->datatype->type,
8925 unew->info->datatype->type))
8934 ("Type %q %s with inconsistent type: %t",
8935 uentry_getName (unew),
8936 uentry_reDefDecl (old, unew),
8937 unew->info->datatype->type),
8938 uentry_whereDeclared (unew)))
8940 uentry_showWhereLastExtra
8941 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8944 old->info->datatype->type = unew->info->datatype->type;
8949 if (!qual_isUnknown (unew->info->datatype->abs))
8951 if (qual_isConcrete (old->info->datatype->abs)
8952 && qual_isEitherAbstract (unew->info->datatype->abs))
8954 if (!ctype_isDirectBool (old->utype))
8959 ("Datatype %q inconsistently %rdeclared as abstract type",
8960 uentry_getName (unew),
8961 uentry_isDeclared (old)),
8962 uentry_whereDeclared (unew)))
8964 uentry_showWhereLastPlain (old);
8968 else if (qual_isEitherAbstract (old->info->datatype->abs)
8969 && qual_isConcrete (unew->info->datatype->abs))
8971 if (!ctype_isDirectBool (old->utype))
8976 ("Datatype %q inconsistently %rdeclared as concrete type",
8977 uentry_getName (unew),
8978 uentry_isDeclared (old)),
8979 uentry_whereDeclared (unew)))
8981 uentry_showWhereLastPlain (old);
8992 if (qual_isEitherAbstract (old->info->datatype->abs))
8994 old->sref = unew->sref;
8995 unew->info->datatype->mut = old->info->datatype->mut;
8998 && uentry_isReallySpecified (old))
9003 ("Datatype %q specified as abstract, "
9004 "but abstract annotation not used in declaration",
9005 uentry_getName (unew)),
9006 uentry_whereDeclared (unew)))
9008 uentry_showWhereLastPlain (old);
9014 unew->info->datatype->abs = old->info->datatype->abs;
9016 if (ynm_isMaybe (unew->info->datatype->mut))
9018 if (completeConform && ynm_isOff (old->info->datatype->mut)
9019 && uentry_isReallySpecified (old))
9024 ("Datatype %q specified as immutable, "
9025 "but immutable annotation not used in declaration",
9026 uentry_getName (unew)),
9027 uentry_whereDeclared (unew)))
9029 uentry_showWhereLastPlain (old);
9033 unew->info->datatype->mut = old->info->datatype->mut;
9035 else if (ynm_isMaybe (old->info->datatype->mut))
9037 old->info->datatype->mut = unew->info->datatype->mut;
9041 if (qual_isEitherAbstract (old->info->datatype->abs))
9043 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
9047 message ("Datatype %q inconsistently %rdeclared as immutable",
9048 uentry_getName (unew),
9049 uentry_isDeclared (old)),
9050 uentry_whereDeclared (unew)))
9052 uentry_showWhereLastPlain (old);
9057 if (ynm_isOff (old->info->datatype->mut)
9058 && ynm_isOn (unew->info->datatype->mut))
9062 message ("Datatype %q inconsistently %rdeclared as mutable",
9063 uentry_getName (unew),
9064 uentry_isDeclared (old)),
9065 uentry_whereDeclared (unew)))
9067 uentry_showWhereLastPlain (old);
9072 old->info->datatype->mut = unew->info->datatype->mut;
9075 uentry_checkStateConformance (old, unew, mustConform, completeConform);
9079 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
9080 /*@notnull@*/ uentry unew,
9082 /*@unused@*/ bool completeConform)
9084 multiVal oldval = uentry_getConstantValue (old);
9085 multiVal newval = uentry_getConstantValue (unew);
9087 if (multiVal_isDefined (oldval))
9089 if (multiVal_isDefined (newval))
9091 if (!multiVal_equiv (oldval, newval))
9096 message ("%s %q %rdeclared with inconsistent value: %q",
9097 ekind_capName (unew->ukind),
9098 uentry_getName (unew),
9099 uentry_isDeclared (old),
9100 multiVal_unparse (newval)),
9101 uentry_whereDeclared (unew)))
9103 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
9107 uentry_setConstantValue (unew, multiVal_copy (oldval));
9116 uentry_setConstantValue (old, multiVal_copy (newval));
9121 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9122 /*@notnull@*/ uentry unew, bool mustConform,
9123 bool completeConform)
9125 bool typeError = FALSE;
9126 bool fcnConformance = FALSE;
9128 if (!ekind_equal (unew->ukind, old->ukind))
9131 ** okay, only if one is a function and the other is
9132 ** a variable of type function.
9135 if (unew->ukind == KENUMCONST
9136 && old->ukind == KCONST)
9138 old->ukind = KENUMCONST;
9142 if (unew->ukind == KFCN
9143 && old->ukind == KCONST
9144 && ctype_isUnknown (old->utype))
9147 ** When a function is defined with an unparam macro
9150 uentry_updateInto (old, unew);
9154 if (uentry_isExpandedMacro (old)
9155 && uentry_isEitherConstant (unew))
9157 uentry_updateInto (old, unew);
9161 if (uentry_isEndIter (unew))
9163 if (ctype_isUnknown (old->utype))
9165 if (!uentry_isSpecified (old)
9166 && uentry_isCodeDefined (unew))
9168 if (!fileloc_withinLines (uentry_whereDefined (old),
9169 uentry_whereDeclared (unew), 2))
9170 { /* bogus! will give errors if there is too much whitespace */
9174 ("Iterator finalized name %q does not match name in "
9175 "previous iter declaration (should be end_%q). This iter "
9176 "is declared at %q",
9177 uentry_getName (unew),
9178 uentry_getName (old),
9179 fileloc_unparse (uentry_whereDefined (old))),
9180 uentry_whereDeclared (old));
9184 uentry_updateInto (old, unew);
9189 KindConformanceError (old, unew, mustConform);
9193 if (uentry_isFunction (unew))
9195 if (uentry_isVariable (old))
9197 if (!ctype_isUnknown (old->utype))
9199 if (ctype_isFunction (old->utype))
9201 uentry_makeVarFunction (old);
9202 checkFunctionConformance (old, unew, mustConform,
9204 fcnConformance = TRUE;
9208 KindConformanceError (old, unew, mustConform);
9213 if (uentry_isExpandedMacro (old))
9215 if (fileloc_isUndefined (unew->whereDefined))
9217 unew->whereDefined = fileloc_update (unew->whereDefined,
9221 uentry_updateInto (old, unew);
9222 old->used = unew->used = TRUE;
9227 /* undeclared identifier */
9228 old->utype = unew->utype;
9229 uentry_makeVarFunction (old);
9230 checkFunctionConformance (old, unew, FALSE, FALSE);
9231 fcnConformance = TRUE;
9237 KindConformanceError (old, unew, mustConform);
9240 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9242 if (!ctype_isUnknown (unew->utype))
9244 if (ctype_isFunction (unew->utype))
9246 uentry_makeVarFunction (unew);
9247 checkFunctionConformance (old, unew, mustConform, completeConform);
9248 fcnConformance = TRUE;
9252 KindConformanceError (old, unew, mustConform);
9257 KindConformanceError (old, unew, mustConform);
9262 KindConformanceError (old, unew, mustConform);
9268 ** check parameter lists for functions
9269 ** (before type errors, to get better messages
9272 if (uentry_isFunction (old))
9274 checkFunctionConformance (old, unew, mustConform, completeConform);
9275 fcnConformance = TRUE;
9279 if (!ctype_isUndefined (old->utype))
9281 typeError = checkTypeConformance (old, unew, mustConform);
9288 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9290 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9293 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9295 DPRINTF (("Check datatype: %s / %s",
9296 uentry_unparseFull (old),
9297 uentry_unparseFull (unew)));
9299 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9302 if (uentry_isVariable (old) && uentry_isVariable (unew))
9305 !ctype_matchDef (old->utype, unew->utype))
9310 ("Variable %q %s with inconsistent type (arrays and pointers are "
9311 "not identical in variable declarations): %t",
9312 uentry_getName (unew),
9313 uentry_reDefDecl (old, unew),
9315 uentry_whereDeclared (unew)))
9317 uentry_showWhereLast (old);
9320 ** Avoid repeated errors.
9323 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9325 old->whereDefined = fileloc_update (old->whereDefined,
9333 checkVarConformance (old, unew, mustConform, completeConform);
9338 /* old->utype = unew->utype; */
9342 if (ctype_isConj (old->utype))
9344 if (ctype_isConj (unew->utype))
9346 if (!ctype_sameAltTypes (old->utype, unew->utype))
9350 message ("%s %q inconsistently %rdeclared with "
9351 "alternate types %s "
9352 "(types match, but alternates are not identical, "
9353 "so checking may not be correct)",
9354 ekind_capName (uentry_getKind (old)),
9355 uentry_getName (unew),
9356 uentry_isDeclared (old),
9357 ctype_unparse (unew->utype)),
9358 uentry_whereDeclared (unew)))
9360 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9364 old->utype = unew->utype;
9371 if (ctype_isUnknown (old->utype))
9373 old->utype = unew->utype;
9378 if (unew->ukind == old->ukind)
9381 unew->info = uinfo_copy (old->info, old->ukind);
9384 sRef_storeState (old->sref);
9385 sRef_storeState (unew->sref);
9388 static void uentry_mergeConstraints (uentry spec, uentry def)
9390 if (uentry_isFunction (def))
9392 DPRINTF (("Here: %s / %s",
9393 uentry_unparseFull (spec),
9394 uentry_unparseFull (def)));
9395 /* evans 2001-07-21 */
9396 llassert (uentry_isFunction (spec));
9398 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9400 if (fileloc_isXHFile (uentry_whereLast (def)))
9402 llassert (uentry_isFunction (spec));
9403 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9404 def->info->fcn->preconditions);
9406 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9412 /* Check if the constraints are identical */
9417 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9418 uentry_getName (spec),
9419 functionConstraint_unparse (spec->info->fcn->preconditions)),
9420 uentry_whereLast (def)))
9422 uentry_showWhereSpecified (spec);
9425 functionConstraint_free (spec->info->fcn->preconditions);
9426 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9429 def->info->fcn->preconditions = functionConstraint_undefined;
9432 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9434 if (fileloc_isXHFile (uentry_whereLast (def)))
9436 llassert (uentry_isFunction (spec));
9437 DPRINTF (("Post: %s /++/ %s",
9438 functionConstraint_unparse (spec->info->fcn->postconditions),
9439 functionConstraint_unparse (def->info->fcn->postconditions)));
9440 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9441 def->info->fcn->postconditions);
9442 def->info->fcn->postconditions = functionConstraint_undefined;
9443 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9450 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9451 uentry_getName (spec),
9452 functionConstraint_unparse (spec->info->fcn->postconditions)),
9453 uentry_whereLast (def)))
9455 uentry_showWhereSpecified (spec);
9458 functionConstraint_free (spec->info->fcn->postconditions);
9459 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9460 def->info->fcn->postconditions = functionConstraint_undefined;
9467 ** modifies spec to reflect def, reports any inconsistencies
9471 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9473 llassert (uentry_isValid (spec));
9474 llassert (uentry_isValid (def));
9475 llassert (cstring_equal (spec->uname, def->uname));
9477 if (uentry_isFunction (def))
9479 if (uentry_isConstant (spec))
9481 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9482 uentry_makeConstantFunction (spec);
9486 uentry_convertVarFunction (spec);
9489 llassert (uentry_isFunction (spec));
9492 DPRINTF (("Merge entries: %s / %s", uentry_unparseFull (spec),
9493 uentry_unparseFull (def)));
9495 uentry_mergeConstraints (spec, def);
9497 uentry_checkConformance (spec, def, TRUE,
9498 context_getFlag (FLG_NEEDSPEC));
9500 DPRINTF (("Merge entries after conform: %s / %s",
9501 uentry_unparseFull (spec),
9502 uentry_unparseFull (def)));
9504 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9507 ** okay, declarations conform. Propagate extra information.
9510 uentry_setDefined (spec, uentry_whereDefined (def));
9511 uentry_setDeclared (spec, uentry_whereDeclared (def));
9513 if (uentry_isStatic (def))
9517 message ("%s %q specified, but declared as static",
9518 ekind_capName (def->ukind),
9519 uentry_getName (def)),
9520 uentry_whereDeclared (def)))
9522 uentry_showWhereSpecified (spec);
9527 spec->storageclass = def->storageclass;
9530 sRef_storeState (spec->sref);
9532 spec->used = def->used || spec->used;
9533 spec->hasNameError |= def->hasNameError;
9537 if (!spec->hasNameError)
9539 uentry_checkName (spec);
9548 ** Can't generate function redeclaration errors when the
9549 ** entries are merged, since we don't yet know if its the
9550 ** definition of the function.
9554 uentry_clearDecl (void)
9556 posRedeclared = uentry_undefined;
9557 fileloc_free (posLoc);
9558 posLoc = fileloc_undefined;
9562 uentry_checkDecl (void)
9564 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9566 llassert (fileloc_isDefined (posLoc));
9568 if (uentry_isCodeDefined (posRedeclared))
9570 if (optgenerror (FLG_REDECL,
9571 message ("%s %q declared after definition",
9572 ekind_capName (posRedeclared->ukind),
9573 uentry_getName (posRedeclared)),
9576 llgenindentmsg (message ("Definition of %q",
9577 uentry_getName (posRedeclared)),
9578 posRedeclared->whereDeclared);
9583 if (optgenerror (FLG_REDECL,
9584 message ("%s %q declared more than once",
9585 ekind_capName (posRedeclared->ukind),
9586 uentry_getName (posRedeclared)),
9589 llgenindentmsg (message ("Previous declaration of %q",
9590 uentry_getName (posRedeclared)),
9591 posRedeclared->whereDeclared);
9596 fileloc_free (posLoc);
9597 posLoc = fileloc_undefined;
9598 posRedeclared = uentry_undefined;
9602 ** Redefinition of old as unew.
9603 ** modifies old to reflect unew, reports any inconsistencies
9607 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9609 fileloc olddef = uentry_whereDeclared (old);
9610 fileloc unewdef = uentry_whereDeclared (unew);
9614 DPRINTF (("uentry merge: %s / %s",
9615 uentry_unparseFull (old),
9616 uentry_unparseFull (unew)));
9619 fileloc_isUndefined (olddef)
9620 && fileloc_isDefined (uentry_whereDefined (old))
9621 && !uentry_isExpandedMacro (old);
9623 if (!context_getFlag (FLG_INCONDEFSLIB)
9624 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9626 mustConform = FALSE;
9633 llassert (uentry_isValid (old));
9634 llassert (uentry_isValid (unew));
9635 llassert (cstring_equal (old->uname, unew->uname));
9637 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9639 if (uentry_isConstant (old))
9641 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9642 uentry_makeConstantFunction (old);
9646 uentry_convertVarFunction (old);
9649 if (!uentry_isFunction (old))
9653 message ("%s %q declared as function, but previously declared as %s",
9654 ekind_capName (unew->ukind),
9655 uentry_getName (unew),
9656 ekind_unparseLong (old->ukind)),
9657 uentry_whereDeclared (unew)))
9659 uentry_showWhereLast (old);
9662 uentry_convertIntoFunction (old);
9667 DPRINTF (("uentry merge: %s / %s",
9668 uentry_unparseFull (old),
9669 uentry_unparseFull (unew)));
9671 if (uentry_isExtern (unew))
9673 uentry_setUsed (old, unewdef);
9677 ** should check old one was extern!
9680 if (uentry_isStatic (old))
9682 if (!(uentry_isStatic (unew)))
9686 message ("%s %q shadows static declaration",
9687 ekind_capName (unew->ukind),
9688 uentry_getName (unew)),
9691 uentry_showWhereLast (old);
9696 uentry_setDeclDef (old, unewdef);
9699 else if (uentry_isStatic (unew))
9701 uentry_setDeclDef (old, unewdef);
9703 else if (uentry_isExtern (old))
9705 uentry_setDeclared (old, unewdef);
9709 if (!uentry_isExtern (unew)
9710 && !uentry_isForward (old)
9711 && !fileloc_equal (olddef, unewdef)
9712 && !fileloc_isUndefined (olddef)
9713 && !fileloc_isUndefined (unewdef)
9714 && !fileloc_isBuiltin (olddef)
9715 && !fileloc_isBuiltin (unewdef)
9716 && !uentry_isYield (old)
9717 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9719 if (uentry_isVariable (old) || uentry_isVariable (unew))
9721 ; /* will report redeclaration error later */
9725 if (fileloc_isDefined (uentry_whereDefined (old)))
9729 message ("%s %q defined more than once",
9730 ekind_capName (unew->ukind),
9731 uentry_getName (unew)),
9732 uentry_whereLast (unew)))
9735 (message ("Previous definition of %q",
9736 uentry_getName (old)),
9737 uentry_whereLast (old));
9740 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9742 uentry_updateInto (old, unew);
9743 old->sref = sRef_saveCopy (old->sref);
9751 if (fileloc_isLib (olddef)
9752 || fileloc_isUndefined (olddef)
9753 || fileloc_isImport (olddef))
9755 if (uentry_isExtern (unew))
9757 if (uentry_isExtern (old)
9758 || (fileloc_isDefined (uentry_whereDeclared (old))
9759 && (!fileloc_equal (uentry_whereDeclared (old),
9760 uentry_whereDefined (old)))))
9764 message ("%s %q declared more than once",
9765 ekind_capName (unew->ukind),
9766 uentry_getName (unew)),
9767 unew->whereDeclared))
9770 (message ("Previous declaration of %q",
9771 uentry_getName (old)),
9772 old->whereDeclared);
9776 uentry_setExtern (old);
9780 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9786 DPRINTF (("uentry merge: %s / %s",
9787 uentry_unparseFull (old),
9788 uentry_unparseFull (unew)));
9790 uentry_mergeConstraints (old, unew);
9791 DPRINTF (("uentry merge: %s / %s",
9792 uentry_unparseFull (old),
9793 uentry_unparseFull (unew)));
9795 uentry_checkConformance (old, unew, mustConform, FALSE);
9796 DPRINTF (("uentry merge: %s / %s",
9797 uentry_unparseFull (old),
9798 uentry_unparseFull (unew)));
9800 old->used = old->used || unew->used;
9801 old->uses = filelocList_append (old->uses, unew->uses);
9802 unew->uses = filelocList_undefined;
9804 sRef_storeState (old->sref);
9805 sRef_storeState (unew->sref);
9809 old->whereDefined = fileloc_update (old->whereDefined,
9813 DPRINTF (("here: %s", uentry_unparseFull (old)));
9816 ** No redeclaration errors for functions here, since we
9817 ** don't know if this is the definition of the function.
9820 if (fileloc_isUser (old->whereDeclared)
9821 && fileloc_isUser (unew->whereDeclared)
9822 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9823 && !fileloc_isDefined (unew->whereDefined))
9825 if (uentry_isFunction (old))
9827 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9828 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9832 if (optgenerror (FLG_REDECL,
9833 message ("%s %q declared more than once",
9834 ekind_capName (unew->ukind),
9835 uentry_getName (unew)),
9836 unew->whereDeclared))
9838 llgenindentmsg (message ("Previous declaration of %q",
9839 uentry_getName (old)),
9840 old->whereDeclared);
9845 if (fileloc_isUndefined (old->whereDefined))
9847 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9851 if (!context_processingMacros ()
9852 && fileloc_isUser (old->whereDefined)
9853 && fileloc_isUser (unew->whereDefined)
9854 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9856 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9858 if (uentry_isVariable (unew)
9859 && uentry_isExtern (unew))
9861 if (optgenerror (FLG_REDECL,
9862 message ("%s %q declared after definition",
9863 ekind_capName (unew->ukind),
9864 uentry_getName (unew)),
9865 unew->whereDeclared))
9867 llgenindentmsg (message ("Definition of %q",
9868 uentry_getName (old)),
9874 if (optgenerror (FLG_REDEF,
9875 message ("%s %q redefined",
9876 ekind_capName (unew->ukind),
9877 uentry_getName (unew)),
9878 unew->whereDefined))
9880 llgenindentmsg (message ("Previous definition of %q",
9881 uentry_getName (old)),
9889 if (uentry_isExternal (unew))
9891 old->whereDefined = fileloc_createExternal ();
9894 if (unew->hasNameError)
9896 old->hasNameError = TRUE;
9901 if (!old->hasNameError)
9903 uentry_checkName (old);
9906 DPRINTF (("After: %s", uentry_unparseFull (old)));
9907 llassert (!ctype_isUndefined (old->utype));
9911 uentry_copyState (uentry res, uentry other)
9913 llassert (uentry_isValid (res));
9914 llassert (uentry_isValid (other));
9916 res->used = other->used;
9918 res->info->var->kind = other->info->var->kind;
9919 res->info->var->defstate = other->info->var->defstate;
9920 res->info->var->nullstate = other->info->var->nullstate;
9921 res->info->var->checked = other->info->var->checked;
9923 sRef_copyState (res->sref, other->sref);
9927 uentry_sameKind (uentry u1, uentry u2)
9929 if (uentry_isValid (u1) && uentry_isValid (u2))
9931 if (uentry_isVar (u1) && uentry_isVar (u2))
9933 ctype c1 = u1->utype;
9934 ctype c2 = u2->utype;
9936 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9939 ** both functions, or both not functions
9942 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9946 return ((u1->ukind == u2->ukind));
9953 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9956 llassert (uentry_isValid (unew));
9957 llassert (uentry_isValid (old));
9959 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9960 okind = unew->ukind;
9961 unew->ukind = old->ukind;
9962 llassert (cstring_equal (unew->uname, old->uname));
9963 unew->utype = old->utype;
9965 if (fileloc_isDefined (unew->whereSpecified)
9966 && !fileloc_isDefined (old->whereSpecified))
9968 ; /* Keep the old value */
9972 fileloc_free (unew->whereSpecified);
9973 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9976 if (fileloc_isDefined (unew->whereDefined)
9977 && !fileloc_isDefined (old->whereDefined))
9979 ; /* Keep the old value */
9983 fileloc_free (unew->whereDefined);
9984 unew->whereDefined = fileloc_copy (old->whereDefined);
9987 if (fileloc_isDefined (unew->whereDeclared)
9988 && !fileloc_isDefined (old->whereDeclared))
9990 ; /* Keep the old value */
9994 fileloc_free (unew->whereDeclared);
9995 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9998 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
10000 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
10001 unew->used = old->used;
10002 unew->lset = FALSE;
10003 unew->isPrivate = old->isPrivate;
10004 unew->hasNameError = old->hasNameError;
10005 unew->uses = filelocList_append (unew->uses, old->uses);
10006 old->uses = filelocList_undefined;
10008 unew->storageclass = old->storageclass;
10009 uinfo_free (unew->info, okind);
10010 unew->info = uinfo_copy (old->info, old->ukind);
10014 uentry_copyAux (uentry e, bool saveCopy)
10017 if (uentry_isValid (e))
10019 uentry enew = uentry_alloc ();
10020 DPRINTF (("copy: %s", uentry_unparseFull (e)));
10021 enew->ukind = e->ukind;
10022 enew->uname = cstring_copy (e->uname);
10023 enew->utype = e->utype;
10025 enew->whereSpecified = fileloc_copy (e->whereSpecified);
10026 enew->whereDefined = fileloc_copy (e->whereDefined);
10027 enew->whereDeclared = fileloc_copy (e->whereDeclared);
10031 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
10035 enew->sref = sRef_copy (e->sref);
10038 enew->used = e->used;
10039 enew->lset = FALSE;
10040 enew->isPrivate = e->isPrivate;
10041 enew->hasNameError = e->hasNameError;
10042 enew->uses = filelocList_undefined;
10044 enew->storageclass = e->storageclass;
10045 enew->info = uinfo_copy (e->info, e->ukind);
10046 enew->warn = warnClause_copy (e->warn);
10048 DPRINTF (("Here we are..."));
10049 DPRINTF (("original: %s", uentry_unparseFull (e)));
10050 DPRINTF (("copy: %s", uentry_unparse (enew)));
10051 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
10056 return uentry_undefined;
10061 uentry_copy (uentry e)
10063 return uentry_copyAux (e, TRUE);
10067 uentry_copyNoSave (uentry e)
10069 return uentry_copyAux (e, FALSE);
10073 uentry_setState (uentry res, uentry other)
10075 llassert (uentry_isValid (res));
10076 llassert (uentry_isValid (other));
10078 llassert (res->ukind == other->ukind);
10079 llassert (res->ukind == KVAR);
10081 res->sref = sRef_saveCopy (other->sref);
10082 res->used = other->used;
10083 filelocList_free (res->uses);
10084 res->uses = other->uses;
10085 other->uses = filelocList_undefined;
10086 res->lset = other->lset;
10090 uentry_mergeUses (uentry res, uentry other)
10092 llassert (uentry_isValid (res));
10093 llassert (uentry_isValid (other));
10095 res->used = other->used || res->used;
10096 res->lset = other->lset || res->lset;
10097 res->uses = filelocList_append (res->uses, other->uses);
10098 other->uses = filelocList_undefined;
10103 ** This is a really ugly routine.
10105 ** gack...fix this one day.
10110 ** >> res is the false branch, other is the true branch (or continuation)
10112 ** >> res is the true branch, other is the false branch (or continutation)
10119 ** References not effected by res are propagated from other.
10123 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10124 bool flip, clause cl, fileloc loc)
10128 message ("%s %q is %s %s, but %s %s.",
10129 ekind_capName (res->ukind), uentry_getName (res),
10130 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
10131 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
10134 DPRINTF (("Here: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10136 if (sRef_isDead (res->sref))
10138 if (sRef_hasStateInfoLoc (res->sref)) {
10139 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10140 sRef_showStateInfo (res->sref);
10143 if (sRef_hasStateInfoLoc (other->sref)) {
10144 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10145 sRef_showStateInfo (other->sref);
10148 else if (sRef_isKept (res->sref))
10150 if (sRef_hasAliasInfoLoc (res->sref)) {
10151 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10152 sRef_showAliasInfo (res->sref);
10155 if (sRef_hasAliasInfoLoc (other->sref)) {
10156 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10157 sRef_showAliasInfo (other->sref);
10160 else /* dependent */
10162 if (sRef_hasAliasInfoLoc (res->sref)) {
10163 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10164 sRef_showAliasInfo (res->sref);
10167 if (sRef_hasAliasInfoLoc (other->sref)) {
10168 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10169 sRef_showAliasInfo (other->sref);
10173 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10177 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
10179 alkind rk = sRef_getAliasKind (rs);
10180 alkind ok = sRef_getAliasKind (os);
10182 if (alkind_isError (rk) || alkind_isError (ok))
10188 return ((sRef_isDead (rs)
10189 || (alkind_isKept (rk) && !alkind_isKept (ok))
10190 || (alkind_isDependent (rk)
10191 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10192 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10197 branchStateAltError (/*@notnull@*/ uentry res,
10198 /*@notnull@*/ uentry other, bool flip,
10199 clause cl, fileloc loc)
10203 message ("%s %q is %s %s, but %s %s.",
10204 ekind_capName (res->ukind), uentry_getName (res),
10205 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10206 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10209 if (sRef_isDead (other->sref))
10211 if (sRef_hasStateInfoLoc (other->sref)) {
10212 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10213 sRef_showStateInfo (other->sref);
10216 if (sRef_hasStateInfoLoc (res->sref)) {
10217 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10218 sRef_showStateInfo (res->sref);
10223 if (sRef_hasAliasInfoLoc (other->sref)) {
10224 llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc);
10225 sRef_showAliasInfo (other->sref);
10228 if (sRef_hasAliasInfoLoc (res->sref)) {
10229 llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc);
10230 sRef_showAliasInfo (res->sref);
10234 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10235 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10237 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10238 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10243 ** A reference is relevant for certain checks, only if it
10244 ** is not definitely null on this path (but not declared
10245 ** to always be null.)
10248 static bool uentry_relevantReference (sRef sr, bool flip)
10250 if (sRef_isKept (sr) || sRef_isDependent (sr))
10258 return !sRef_definitelyNullContext (sr);
10262 return !sRef_definitelyNullAltContext (sr);
10268 uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10269 fileloc loc, bool mustReturn, bool flip, bool opt,
10272 sRef rs = res->sref;
10273 sRef os = other->sref;
10275 DPRINTF (("Merge alias states: %s / %s",
10276 uentry_unparseFull (res),
10277 uentry_unparseFull (other)));
10279 if (sRef_isValid (rs))
10283 if (uentry_incompatibleMemoryStates (rs, os))
10285 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10286 sRef_unparseFull (rs), sRef_unparseFull (os)));
10288 if (sRef_isThroughArrayFetch (rs)
10289 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10291 if (sRef_isKept (rs) || sRef_isKept (os))
10293 sRef_maybeKill (rs, loc);
10295 else if (sRef_isPossiblyDead (os))
10297 sRef_maybeKill (rs, loc);
10306 if (uentry_relevantReference (os, flip))
10308 if (sRef_isLocalParamVar (rs)
10309 && (sRef_isLocalState (os)
10310 || sRef_isDependent (os)))
10312 if (sRef_isDependent (rs))
10314 sRef_setDependent (os, loc);
10318 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10323 branchStateError (res, other, !flip, cl, loc); /* evans 2002-12-15: changed flip to !flip */
10328 if (sRef_isKept (rs))
10330 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10331 sRef_setKept (os, loc);
10336 if (uentry_incompatibleMemoryStates (os, rs))
10338 if (uentry_relevantReference (rs, !flip))
10340 if (sRef_isLocalParamVar (rs)
10341 && (sRef_isDependent (rs)
10342 || sRef_isLocalState (rs)))
10344 if (sRef_isDependent (os))
10346 sRef_setDependent (rs, loc);
10350 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10355 if (sRef_isParam (os))
10358 ** If the local variable associated
10359 ** with the param has the correct state,
10361 ** (e.g., free (s); s = new(); ...
10364 uentry uvar = usymtab_lookupSafe (other->uname);
10366 if (uentry_isValid (uvar)
10367 && ((sRef_isDead (os)
10368 && sRef_isOnly (uvar->sref))
10369 || (sRef_isDependent (os)
10370 && sRef_isOwned (uvar->sref))))
10376 branchStateAltError (res, other,
10382 DPRINTF (("Here: %s / %s",
10383 uentry_unparseFull (res),
10384 uentry_unparseFull (other)));
10386 branchStateAltError (res, other,
10393 if (sRef_isKept (os))
10395 sRef_setKept (rs, loc);
10401 DPRINTF (("Merge opt..."));
10402 sRef_mergeOptState (rs, os, cl, loc);
10403 DPRINTF (("Done!"));
10407 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10408 sRef_mergeState (rs, os, cl, loc);
10409 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10414 if (sRef_isModified (os))
10416 sRef_setModified (rs);
10421 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10425 uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
10426 fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10428 valueTable rvalues;
10429 valueTable ovalues;
10431 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10439 rvalues = sRef_getValueTable (res->sref);
10440 ovalues = sRef_getValueTable (other->sref);
10442 if (valueTable_isUndefined (ovalues))
10444 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10447 else if (valueTable_isUndefined (rvalues))
10450 ** Copy values from other
10457 valueTable_elements (ovalues, fkey, fval) {
10459 metaStateInfo minfo;
10460 stateCombinationTable sctable;
10464 tval = valueTable_lookup (rvalues, fkey);
10466 DPRINTF (("Merge value: %s / %s X %s", fkey,
10467 stateValue_unparse (fval), stateValue_unparse (tval)));
10469 minfo = context_lookupMetaStateInfo (fkey);
10470 llassert (stateValue_isDefined (tval));
10472 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10474 DPRINTF (("Cannot find meta state for: %s", fkey));
10479 llassert (metaStateInfo_isDefined (minfo));
10481 if (stateValue_isError (fval)
10482 || sRef_definitelyNullContext (res->sref))
10484 sRef_setMetaStateValueComplete (res->sref,
10485 fkey, stateValue_getValue (fval),
10486 stateValue_getLoc (fval));
10487 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10489 else if (stateValue_isError (tval)
10490 || sRef_definitelyNullAltContext (other->sref))
10492 DPRINTF (("Other branch is definitely null!"));
10494 else if (sRef_isStateUndefined (res->sref)
10495 || sRef_isDead (res->sref))
10497 ; /* Combination state doesn't matter if it is undefined or dead */
10501 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10502 metaStateInfo_unparse (minfo),
10503 stateValue_unparse (fval),
10504 stateValue_unparse (tval)));
10506 DPRINTF (("state values: %d / %d",
10507 stateValue_getValue (fval), stateValue_getValue (tval)));
10509 sctable = metaStateInfo_getMergeTable (minfo);
10511 DPRINTF (("Merge table: %s",
10512 stateCombinationTable_unparse (sctable)));
10514 msg = cstring_undefined;
10516 nval = stateCombinationTable_lookup (sctable,
10517 stateValue_getValue (fval),
10518 stateValue_getValue (tval),
10521 DPRINTF (("nval: %d / %d / %d", nval,
10522 stateValue_getValue (fval), stateValue_getValue (tval)));
10524 if (nval == stateValue_error)
10526 if (uentry_isGlobalMarker (res))
10531 ("Control branches merge with incompatible global states (%s and %s)%q",
10532 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10533 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10534 cstring_isDefined (msg)
10535 ? message (": %s", msg) : cstring_undefined),
10538 sRef_showMetaStateInfo (res->sref, fkey);
10539 sRef_showMetaStateInfo (other->sref, fkey);
10547 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10548 uentry_getName (res),
10549 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10550 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10551 cstring_isDefined (msg)
10552 ? message (": %s", msg) : cstring_undefined),
10555 sRef_showMetaStateInfo (res->sref, fkey);
10556 sRef_showMetaStateInfo (other->sref, fkey);
10557 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10558 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10559 DPRINTF (("Null: %s / %s",
10560 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10561 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10567 if (nval == stateValue_getValue (fval)
10568 && nval != stateValue_getValue (tval))
10570 loc = stateValue_getLoc (fval);
10572 else if (nval == stateValue_getValue (tval)
10573 && nval != stateValue_getValue (fval))
10575 loc = stateValue_getLoc (tval);
10582 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10583 && nval == stateValue_getValue (fval)
10584 && nval == stateValue_getValue (tval))
10590 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10594 } end_valueTable_elements ;
10600 uentry_mergeSetStates (/*@notnull@*/ uentry res,
10601 /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
10602 bool flip, clause cl)
10604 if (cl == DOWHILECLAUSE)
10606 res->used = other->used || res->used;
10607 res->lset = other->lset || res->lset;
10608 res->uses = filelocList_append (res->uses, other->uses);
10609 other->uses = filelocList_undefined;
10613 if (sRef_isMacroParamRef (res->sref)
10614 && !uentry_isSefParam (other)
10615 && !uentry_isSefParam (res))
10617 bool hasError = FALSE;
10619 if (bool_equal (res->used, other->used))
10621 res->used = other->used;
10625 if (other->used && !flip)
10630 message ("Macro parameter %q used in true clause, "
10631 "but not in false clause",
10632 uentry_getName (res)),
10633 uentry_whereDeclared (res));
10640 message ("Macro parameter %q used in false clause, "
10641 "but not in true clause",
10642 uentry_getName (res)),
10643 uentry_whereDeclared (res));
10649 /* make it sef now, prevent more errors */
10650 res->info->var->kind = VKREFSEFPARAM;
10656 res->used = other->used || res->used;
10657 res->lset = other->lset || res->lset;
10658 res->uses = filelocList_append (res->uses, other->uses);
10659 other->uses = filelocList_undefined;
10665 uentry_mergeState (uentry res, uentry other, fileloc loc,
10666 bool mustReturn, bool flip, bool opt,
10669 llassert (uentry_isValid (res));
10670 llassert (uentry_isValid (other));
10672 llassert (res->ukind == other->ukind);
10673 llassert (res->ukind == KVAR);
10675 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10676 uentry_unparseFull (other)));
10678 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10679 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10680 uentry_mergeSetStates (res, other, loc, flip, cl);
10682 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
10685 void uentry_setUsed (uentry e, fileloc loc)
10687 static bool firstTime = TRUE;
10688 static bool showUses = FALSE;
10689 static bool exportLocal = FALSE;
10691 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10695 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10697 showUses = context_getFlag (FLG_SHOWUSES);
10698 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10703 if (uentry_isValid (e))
10705 if (warnClause_isDefined (e->warn))
10707 flagSpec flg = warnClause_getFlag (e->warn);
10710 if (warnClause_hasMessage (e->warn))
10712 msg = cstring_copy (warnClause_getMessage (e->warn));
10716 msg = message ("Use of possibly dangerous %s",
10717 uentry_ekindNameLC (e));
10721 message ("%q: %q", msg, uentry_getName (e)),
10725 if (sRef_isMacroParamRef (e->sref))
10727 if (uentry_isYield (e) || uentry_isSefParam (e))
10733 if (context_inConditional ())
10737 message ("Macro parameter %q used in conditionally "
10738 "executed code (may or may not be "
10739 "evaluated exactly once)",
10740 uentry_getName (e)),
10743 e->info->var->kind = VKREFSEFPARAM;
10752 message ("Macro parameter %q used more than once",
10753 uentry_getName (e)),
10754 uentry_whereDeclared (e)))
10756 e->info->var->kind = VKREFSEFPARAM;
10763 if (usymId_isValid (usymtab_directParamNo (e)))
10765 uentry_setUsed (usymtab_getParam (usymId_toInt (usymtab_directParamNo (e))), loc);
10770 if (!sRef_isLocalVar (e->sref))
10774 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10780 if (context_inMacro ())
10782 e->uses = filelocList_addUndefined (e->uses);
10786 e->uses = filelocList_addDifferentFile
10788 uentry_whereDeclared (e),
10797 bool uentry_isReturned (uentry u)
10799 return (uentry_isValid (u) && uentry_isVar (u)
10800 && (u->info->var->kind == VKRETPARAM
10801 || u->info->var->kind == VKSEFRETPARAM));
10804 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args, fileloc loc)
10806 llassert (uentry_isRealFunction (u));
10808 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10810 stateClauseList clauses = uentry_getStateClauseList (u);
10811 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10813 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10814 sRef_setAllocated (res, loc);
10816 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10817 stateClauseList_unparse (clauses)));
10820 ** This should be in exprNode_reflectEnsuresClause
10823 stateClauseList_postElements (clauses, cl)
10825 if (!stateClause_isGlobal (cl))
10827 sRefSet refs = stateClause_getRefs (cl);
10828 sRefMod modf = stateClause_getEffectFunction (cl);
10830 sRefSet_elements (refs, el)
10832 sRef base = sRef_getRootBase (el);
10834 if (sRef_isResult (base))
10838 sRef sr = sRef_fixBase (el, res);
10846 } end_sRefSet_elements ;
10848 } end_stateClauseList_postElements ;
10856 sRefSet prefs = sRefSet_new ();
10857 sRef res = sRef_undefined;
10860 params = uentry_getParams (u);
10862 uentryList_elements (params, current)
10864 if (uentry_isReturned (current))
10866 if (exprNodeList_size (args) >= paramno)
10868 exprNode ecur = exprNodeList_nth (args, paramno);
10869 sRef tref = exprNode_getSref (ecur);
10871 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10873 if (sRef_isValid (tref))
10875 sRef tcref = sRef_copy (tref);
10877 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10879 if (sRef_isNew (tcref))
10881 /* tcref->kind = SK_OBJECT; */ /*!! Not new anymore */
10884 if (sRef_isDead (tcref))
10886 sRef_setDefined (tcref, loc);
10887 sRef_setOnly (tcref, loc);
10890 if (sRef_isRefCounted (tcref))
10892 /* could be a new ref now (but only if its returned) */
10893 sRef_setAliasKindComplete (tcref, AK_ERROR, loc);
10896 sRef_makeSafe (tcref);
10897 DPRINTF (("Returns tcref / %s", sRef_unparseFull (tcref)));
10898 prefs = sRefSet_insert (prefs, tcref);
10904 } end_uentryList_elements ;
10906 if (sRefSet_size (prefs) > 0)
10908 nstate n = sRef_getNullState (u->sref);
10910 if (sRefSet_size (prefs) == 1)
10912 res = sRefSet_choose (prefs);
10916 /* should this ever happen? */
10917 res = sRefSet_mergeIntoOne (prefs);
10920 if (nstate_isKnown (n))
10922 sRef_setNullState (res, n, loc);
10927 if (ctype_isFunction (u->utype))
10929 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10930 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10934 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10937 if (sRef_isRefCounted (res))
10939 sRef_setAliasKind (res, AK_NEWREF, loc);
10944 if (sRef_getNullState (res) == NS_ABSNULL)
10946 ctype ct = ctype_realType (u->utype);
10948 if (ctype_isAbstract (ct))
10950 sRef_setNotNull (res, loc);
10954 if (ctype_isUser (ct))
10956 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10960 sRef_setNotNull (res, loc);
10965 if (sRef_isRefCounted (res))
10967 sRef_setAliasKind (res, AK_NEWREF, loc);
10969 else if (sRef_isKillRef (res))
10971 sRef_setAliasKind (res, AK_REFCOUNTED, loc);
10978 ak = sRef_getAliasKind (res);
10980 if (alkind_isImplicit (ak))
10982 sRef_setAliasKind (res,
10983 alkind_fixImplicit (ak),
10987 sRefSet_free (prefs);
10990 if (sRef_isOnly (res))
10992 sRef_setFresh (res, loc);
10996 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
11001 static bool uentry_isRefCounted (uentry ue)
11003 ctype ct = uentry_getType (ue);
11005 if (ctype_isFunction (ct))
11007 return (ctype_isRefCounted (ctype_getReturnType (ct)));
11011 return (ctype_isRefCounted (ct));
11016 ** old was declared yield in the specification.
11017 ** new is declared in the iter implementation.
11020 void uentry_checkYieldParam (uentry old, uentry unew)
11024 llassert (uentry_isVariable (old));
11025 llassert (uentry_isVariable (unew));
11027 unew->info->var->kind = VKYIELDPARAM;
11028 (void) checkTypeConformance (old, unew, TRUE);
11029 checkVarConformance (old, unew, TRUE, FALSE);
11031 /* get rid of param marker */
11033 name = uentry_getName (unew);
11034 cstring_free (unew->uname);
11035 unew->uname = name;
11036 unew->info->var->kind = VKREFYIELDPARAM;
11038 uentry_setUsed (old, fileloc_undefined);
11039 uentry_setUsed (unew, fileloc_undefined);
11042 /*@observer@*/ cstring
11043 uentry_ekindName (uentry ue)
11045 if (uentry_isValid (ue))
11050 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
11052 return cstring_makeLiteralTemp ("Datatype");
11054 return cstring_makeLiteralTemp ("Enum member");
11056 return cstring_makeLiteralTemp ("Constant");
11058 if (uentry_isParam (ue))
11060 return cstring_makeLiteralTemp ("Parameter");
11062 else if (uentry_isExpandedMacro (ue))
11064 return cstring_makeLiteralTemp ("Expanded macro");
11068 return cstring_makeLiteralTemp ("Variable");
11071 return cstring_makeLiteralTemp ("Function");
11073 return cstring_makeLiteralTemp ("Iterator");
11075 return cstring_makeLiteralTemp ("Iterator finalizer");
11077 return cstring_makeLiteralTemp ("Struct tag");
11079 return cstring_makeLiteralTemp ("Union tag");
11081 return cstring_makeLiteralTemp ("Enum tag");
11083 return cstring_makeLiteralTemp ("Optional parameters");
11088 return cstring_makeLiteralTemp ("<Undefined>");
11094 /*@observer@*/ cstring
11095 uentry_ekindNameLC (uentry ue)
11097 if (uentry_isValid (ue))
11102 return cstring_makeLiteralTemp ("<error: invalid uentry>");
11104 return cstring_makeLiteralTemp ("datatype");
11106 return cstring_makeLiteralTemp ("enum member");
11108 return cstring_makeLiteralTemp ("constant");
11110 if (uentry_isParam (ue))
11112 return cstring_makeLiteralTemp ("parameter");
11114 else if (uentry_isExpandedMacro (ue))
11116 return cstring_makeLiteralTemp ("expanded macro");
11120 return cstring_makeLiteralTemp ("variable");
11123 return cstring_makeLiteralTemp ("function");
11125 return cstring_makeLiteralTemp ("iterator");
11127 return cstring_makeLiteralTemp ("iterator finalizer");
11129 return cstring_makeLiteralTemp ("struct tag");
11131 return cstring_makeLiteralTemp ("union tag");
11133 return cstring_makeLiteralTemp ("enum tag");
11135 return cstring_makeLiteralTemp ("optional parameters");
11140 return cstring_makeLiteralTemp ("<Undefined>");
11146 void uentry_setHasNameError (uentry ue)
11148 llassert (uentry_isValid (ue));
11150 ue->hasNameError = TRUE;
11153 void uentry_checkName (uentry ue)
11155 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
11156 uentry_observeRealName (ue),
11157 bool_unparse (uentry_isVisibleExternally (ue))));
11159 if (uentry_isValid (ue)
11160 && !context_inXHFile ()
11161 && uentry_hasName (ue)
11162 && !uentry_isElipsisMarker (ue)
11163 && context_getFlag (FLG_NAMECHECKS)
11164 && !ue->hasNameError
11165 && !uentry_isEndIter (ue)
11166 && !fileloc_isBuiltin (uentry_whereLast (ue))
11167 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
11169 DPRINTF (("Here..."));
11171 if (uentry_isPriv (ue))
11173 ; /* any checks here? */
11175 else if (fileloc_isExternal (uentry_whereDefined (ue)))
11177 ; /* no errors for externals */
11183 if (uentry_isExpandedMacro (ue))
11189 if (uentry_isExpandedMacro (ue))
11193 else if (uentry_isVariable (ue))
11195 sRef sr = uentry_getSref (ue);
11197 if (sRef_isValid (sr))
11199 scope = sRef_getScope (sr);
11206 else if (uentry_isFunction (ue)
11207 || uentry_isIter (ue)
11208 || uentry_isEndIter (ue)
11209 || uentry_isConstant (ue))
11211 scope = uentry_isStatic (ue) ? fileScope : globScope;
11213 else /* datatypes, etc. must be global */
11218 usymtab_checkDistinctName (ue, scope);
11221 if (context_getFlag (FLG_CPPNAMES))
11226 if (scope == globScope)
11228 checkExternalName (ue);
11230 else if (scope == fileScope)
11232 checkFileScopeName (ue);
11236 checkLocalName (ue);
11240 checkAnsiName (ue);
11245 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
11251 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11254 if (!context_inMacro ())
11256 sRef_setGlobalScopeSafe ();
11259 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11260 uentry_setUsed (ue, loc);
11262 tloc = fileloc_createExternal ();
11263 uentry_setDefined (ue, tloc);
11264 fileloc_free (tloc);
11265 uentry_setHasNameError (ue);
11267 if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldStyleScope()))
11269 uentry_markOwned (ue);
11273 ue = usymtab_supReturnFileEntry (ue);
11276 if (!context_inMacro ())
11278 sRef_clearGlobalScopeSafe ();
11284 uentry uentry_makeGlobalMarker ()
11289 llassert (sRef_inGlobalScope ());
11291 ue = uentry_makeVariableAux
11292 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11293 sRef_makeGlobalMarker (),
11296 tloc = fileloc_createExternal ();
11297 uentry_setUsed (ue, tloc);
11298 uentry_setDefined (ue, tloc);
11299 fileloc_free (tloc);
11300 uentry_setHasNameError (ue);
11306 bool uentry_isGlobalMarker (uentry ue)
11308 return (uentry_isValid (ue)
11309 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11312 /* new start modifications */
11314 /* start modifications */
11316 requires: p_e is defined, is a ptr/array variable
11318 effects: sets the state of the variable
11322 void uentry_setPossiblyNullTerminatedState (uentry p_e)
11324 llassert (uentry_isValid (p_e));
11326 if (p_e->info != NULL)
11328 if (p_e->info->var != NULL)
11330 llassert (p_e->info->var->bufinfo != NULL);
11331 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11332 sRef_setPossiblyNullTerminatedState (p_e->sref);
11338 requires: p_e is defined, is a ptr/array variable
11340 effects: sets the size of the buffer
11343 void uentry_setNullTerminatedState (uentry p_e) {
11344 llassert (uentry_isValid (p_e));
11346 if (p_e->info != NULL)
11348 if (p_e->info->var != NULL)
11350 llassert (p_e->info->var->bufinfo != NULL);
11351 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11352 sRef_setNullTerminatedState (p_e->sref);
11358 requires: p_e is defined, is a ptr/array variable
11360 effects: sets the size of the buffer
11363 void uentry_setSize (uentry p_e, int size)
11365 if (uentry_isValid (p_e))
11367 if (p_e->info != NULL)
11369 if (p_e->info->var != NULL)
11371 llassert (p_e->info->var->bufinfo != NULL);
11372 p_e->info->var->bufinfo->size = size;
11373 sRef_setSize (p_e->sref, size);
11380 requires: p_e is defined, is a ptr/array variable
11382 effects: sets the length of the buffer
11385 void uentry_setLen (uentry p_e, int len)
11387 if (uentry_isValid (p_e))
11389 if (p_e->info != NULL
11390 && p_e->info->var != NULL)
11392 llassert (p_e->info->var->bufinfo != NULL);
11393 p_e->info->var->bufinfo->len = len;
11394 sRef_setLen (p_e->sref, len);
11401 bool uentry_hasMetaStateEnsures (uentry e)
11403 if (uentry_isValid (e) && uentry_isFunction (e))
11405 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11413 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11415 llassert (uentry_isValid (e) && uentry_isFunction (e));
11416 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
11420 bool uentry_hasBufStateInfo (uentry ue)
11422 llassert (uentry_isValid (ue));
11423 return (ue->info->var->bufinfo != NULL);
11426 bool uentry_isNullTerminated (uentry ue)
11428 llassert (uentry_hasBufStateInfo (ue));
11429 llassert (ue->info->var->bufinfo != NULL);
11430 return ue->info->var->bufinfo->bufstate == BB_NULLTERMINATED;
11433 bool uentry_isPossiblyNullTerminated (uentry ue)
11435 llassert (uentry_hasBufStateInfo (ue));
11436 llassert (ue->info->var->bufinfo != NULL);
11437 return (ue->info->var->bufinfo->bufstate == BB_POSSIBLYNULLTERMINATED);
11440 bool uentry_isNotNullTerminated (uentry ue)
11442 llassert (uentry_hasBufStateInfo (ue));
11443 llassert (ue->info->var->bufinfo != NULL);
11444 return (ue->info->var->bufinfo->bufstate == BB_NOTNULLTERMINATED);
11447 # ifdef DEBUGSPLINT
11450 ** For debugging only
11453 void uentry_checkValid (uentry ue)
11455 if (uentry_isValid (ue))
11457 sRef_checkCompletelyReasonable (ue->sref);