2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
28 # include "lclintMacros.nf"
30 # include "structNames.h"
31 # include "nameChecks.h"
33 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34 static /*@only@*/ fileloc posLoc = fileloc_undefined;
35 static int nuentries = 0;
36 static int totuentries = 0;
38 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
39 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
40 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
41 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
42 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
43 static void uentry_checkIterArgs (uentry p_ue);
44 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
46 static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
49 static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
53 static void checkAliasState (/*@notnull@*/ uentry p_old,
54 /*@notnull@*/ uentry p_unew,
55 bool p_mustConform, bool p_completeConform)
56 /*@modifies p_old, p_unew@*/ ;
57 static void checkNullState (/*@notnull@*/ uentry p_old,
58 /*@notnull@*/ uentry p_unew,
59 bool p_mustConform, bool p_completeConform)
60 /*@modifies p_old, p_unew@*/ ;
62 static void checkVarConformance (/*@notnull@*/ uentry p_old,
63 /*@notnull@*/ uentry p_unew,
64 bool p_mustConform, bool p_completeConform)
65 /*@modifies p_old, p_unew@*/;
68 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
69 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_msgstream@*/ ;
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 void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
95 if (uentry_isVariable (ue)
96 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
97 || ctype_isUnknown (uentry_getType (ue))))
99 uentry_makeVarFunction (ue);
103 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
105 uentry ue = (uentry) dmalloc (sizeof (*ue));
106 ue->warn = warnClause_undefined; /*@i32@*/
113 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
114 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
116 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
117 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
118 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
119 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
120 static void ucinfo_free (/*@only@*/ ucinfo p_u);
121 static void uvinfo_free (/*@only@*/ uvinfo p_u);
125 static /*@only@*/ cstring ancontext_unparse (ancontext an)
129 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
130 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
131 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
132 case AN_SUFIELD: return cstring_makeLiteral ("su field");
133 case AN_TDEFN: return cstring_makeLiteral ("type definition");
134 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
135 case AN_CONST: return cstring_makeLiteral ("constant");
141 static int annots[AN_LAST][QU_LAST];
142 static int decls[AN_LAST];
143 static int shdecls[AN_LAST];
144 static int idecls[AN_LAST];
150 for (i = AN_UNKNOWN; i < AN_LAST; i++)
156 for (j = QU_UNKNOWN; j < QU_LAST; j++)
163 static void tallyAnnot (ancontext ac, qual q)
177 for (j = QU_UNKNOWN; j < QU_LAST; j++)
182 for (i = AN_UNKNOWN; i < AN_LAST; i++)
188 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
189 ancontext_unparse (i),
190 decls[i], shdecls[i], idecls[i]);
192 totdecls += decls[i];
193 totshdecls += shdecls[i];
194 totidecls += idecls[i];
196 for (j = QU_UNKNOWN; j < QU_LAST; j++)
198 total[j] += annots[i][j];
199 alltotals += annots[i][j];
202 printf (" Allocation:\n");
206 for (j = QU_UNKNOWN; j < QU_LAST; j++)
208 if (qual_isAliasQual (j) && !qual_isUnique (j))
210 if (annots[i][j] > 0)
212 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
213 100.0 * (double)annots[i][j] / (double)decls[i]);
214 tmptot += annots[i][j];
219 printf (" Exposure:\n");
223 for (j = QU_UNKNOWN; j < QU_LAST; j++)
225 if (qual_isExQual (j))
227 if (annots[i][j] > 0)
229 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
230 100.0 * (double)annots[i][j] / (double)decls[i]);
231 tmptot += annots[i][j];
236 printf (" Definition:\n");
238 for (j = QU_UNKNOWN; j < QU_LAST; j++)
240 if (qual_isAllocQual (j))
242 if (annots[i][j] > 0)
244 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
245 100.0 * (double)annots[i][j] / (double)decls[i]);
252 for (j = QU_UNKNOWN; j < QU_LAST; j++)
254 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
256 if (annots[i][j] > 0)
258 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
259 100.0 * (double)annots[i][j] / (double)decls[i]);
268 for (j = QU_UNKNOWN; j < QU_LAST; j++)
272 for (i = AN_UNKNOWN; i < AN_LAST; i++)
274 if (annots[i][j] > 0)
283 printf ("Annotation: %s\n", qual_unparse (j));
285 for (i = AN_UNKNOWN; i < AN_LAST; i++)
287 if (annots[i][j] > 0)
289 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
296 printf ("All Contexts\n");
298 for (j = QU_UNKNOWN; j < QU_LAST; j++)
302 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
303 100.0 * (double)total[j] / (double)(totdecls));
308 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
310 extern void uentry_tallyAnnots (uentry u, ancontext kind)
312 alkind ak = sRef_getAliasKind (u->sref);
313 exkind ek = sRef_getExKind (u->sref);
314 nstate ns = sRef_getNullState (u->sref);
315 sstate ss = sRef_getDefState (u->sref);
316 bool recordUnknown = FALSE;
318 if (kind == AN_UNKNOWN)
326 else if (e == KCONST || e == KENUMCONST)
330 else if (e == KFCN || e == KITER)
332 uentryList params = uentry_getParams (u);
335 uentryList_elements (params, current)
337 if (uentry_isReturned (current))
341 if (!uentry_isElipsisMarker (current))
343 uentry_tallyAnnots (current, AN_FCNPARAM);
345 } end_uentryList_elements;
349 if (ctype_isFunction (u->utype)
351 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
353 recordUnknown = TRUE;
356 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
358 ctype t = ctype_realType (u->utype);
362 uentryList fields = ctype_getFields (t);
364 uentryList_elements (fields, current)
366 uentry_tallyAnnots (current, AN_SUFIELD);
368 } end_uentryList_elements;
372 if (ctype_isVisiblySharable (u->utype))
374 recordUnknown = TRUE;
382 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
384 recordUnknown = TRUE;
391 if (kind == AN_FCNRETURN)
405 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
410 if (ctype_isRealPointer (ctype_realType (u->utype)))
418 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
419 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
420 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
421 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
425 if (uentry_isReturned (u))
427 tallyAnnot (kind, QU_RETURNED);
433 if (ctype_isRefCounted (ctype_realType (u->utype))
434 || (ctype_isFunction (u->utype) &&
435 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
441 if (kind == AN_FCNPARAM)
443 tallyAnnot (kind, QU_TEMP);
445 else if (recordUnknown)
447 if (kind == AN_FCNRETURN)
450 tallyAnnot (kind, QU_UNKNOWN);
454 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
455 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
456 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
457 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
459 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
460 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
461 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
462 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
463 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
464 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
465 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
466 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
467 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
468 case AK_IMPDEPENDENT:
469 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
479 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
480 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
486 case NS_ERROR: break;
487 case NS_UNKNOWN: break;
488 case NS_NOTNULL: break;
489 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
490 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
491 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
492 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
494 case NS_ABSNULL: break;
500 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
504 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
505 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
506 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
507 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
508 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
514 static specCode specCode_fromInt (int i)
517 llassert (i >= SPC_NONE && i < SPC_LAST);
519 return ((specCode) i);
523 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
525 if (uentry_isDeclared (u))
527 return cstring_makeLiteralTemp ("previously declared");
531 return cstring_makeLiteralTemp ("specified");
535 /*@observer@*/ cstring uentry_specDeclName (uentry u)
537 if (uentry_isDeclared (u))
539 return cstring_makeLiteralTemp ("previous declaration");
543 return cstring_makeLiteralTemp ("specification");
547 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
549 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
551 return cstring_makeLiteralTemp ("redefined");
553 else if (uentry_isCodeDefined (unew))
555 return cstring_makeLiteralTemp ("defined");
557 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
559 return cstring_makeLiteralTemp ("redeclared");
563 return cstring_makeLiteralTemp ("declared");
567 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
569 if (uentry_isValid (ue))
571 functionConstraint constraint;
573 DPRINTF( (message ("called uentry_getFcnPostconditions on %s",
574 uentry_unparse (ue) ) ) );
576 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
578 DPRINTF( (message ("called uentry_getFunctionConditions on nonfunction %s",
579 uentry_unparse (ue) ) ) );
580 if (!uentry_isFunction (ue) )
582 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
583 uentry_unparse (ue) ) ));
584 return constraintList_undefined;
588 return constraintList_undefined;
591 if (!uentry_isFunction(ue))
594 DPRINTF( (message ("called uentry_getFunctionConditions on non function %s",
595 uentry_unparse (ue) ) ) );
596 return constraintList_undefined;
600 llassert (uentry_isFunction (ue));
604 constraint = ue->info->fcn->postconditions;
608 constraint = ue->info->fcn->preconditions;
611 return functionConstraint_getBufferConstraints (constraint);
614 return constraintList_undefined;
619 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
621 return uentry_getFunctionConditions (ue, FALSE);
628 constraintList uentry_getFcnPostconditions (uentry ue)
630 return uentry_getFunctionConditions (ue, TRUE);
633 static /*@only@*/ fileloc setLocation (void)
635 fileloc fl = context_getSaveLocation ();
637 if (fileloc_isDefined (fl))
643 return fileloc_copy (g_currentloc);
647 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
649 llassert (uentry_isEitherConstant (ue));
650 sRef_setValue (ue->sref, val);
653 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
655 fileloc loc = setLocation ();
656 uentry ue = uentry_makeConstant (n, t, loc);
658 ue->ukind = KENUMCONST;
659 uentry_setDefined (ue, loc);
663 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
665 fileloc loc = setLocation ();
666 uentry ue = uentry_makeConstant (n, t, loc);
667 ctype etype = exprNode_getType (expr);
669 if (!ctype_isRealInt (etype)) {
673 ("Value of enum member is not an integeral type (type %s): %s",
674 ctype_unparse (etype), exprNode_unparse (expr)),
675 exprNode_loc (expr));
678 ue->ukind = KENUMCONST;
679 uentry_setDefined (ue, loc);
684 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
686 uentry ue = uentry_makeConstant (n, t, loc);
688 ue->ukind = KENUMCONST;
693 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
695 return uentry_makeVariable (n, t, setLocation (), FALSE);
699 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
701 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
705 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
707 ctype ct = idDecl_getCtype (id);
708 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
709 MAYBE, MAYBE, setLocation ());
711 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
713 if (!ynm_isOn (ue->info->datatype->abs))
715 if (ctype_isUnknown (ct))
717 ue->info->datatype->mut = MAYBE;
721 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
728 void uentry_checkParams (uentry ue)
730 if (uentry_isValid (ue))
732 bool isExt = uentry_isExtern (ue);
734 if (uentry_isRealFunction (ue))
736 uentryList params = uentry_getParams (ue);
738 uentryList_elements (params, current)
740 if (uentry_isValid (current))
742 ctype ct = current->utype;
744 if (ctype_isFixedArray (ct))
746 if (ctype_isArray (ctype_baseArrayPtr (ct))
747 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
754 (FLG_FIXEDFORMALARRAY,
755 message ("Function parameter %q declared as "
756 "manifest array (size constant is meaningless)",
757 uentry_getName (current)),
758 uentry_whereDeclared (current));
763 if (ctype_isArray (ct))
767 message ("Function parameter %q declared as "
768 "array (treated as pointer)",
769 uentry_getName (current)),
770 uentry_whereDeclared (current));
774 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
776 if (ctype_isAbstract (ct) &&
777 (isExt || (ctype_isAbstract (ctype_realType (ct))
778 && !context_hasFileAccess (ctype_typeId (ct)))))
783 ("Function %q declared with notnull parameter %q of abstract "
786 uentry_getName (current),
789 ("Since %s is an abstract type, notnull can only be "
790 "used for parameters if the function is static to a "
791 "module where %s is accessible.",
794 uentry_whereDeclared (current));
798 } end_uentryList_elements;
800 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
802 ctype ct = ue->utype;
804 if (ctype_isAbstract (ct)
805 && (isExt || (ctype_isAbstract (ctype_realType (ct))
806 && !context_hasFileAccess (ctype_typeId (ct)))))
811 ("%s %q declared %s notnull storage of abstract type %s",
812 ekind_capName (uentry_getKind (ue)),
817 ("Since %s is an abstract type, notnull can only be used "
818 "if it is static to a module where %s is accessible.",
821 uentry_whereDeclared (ue));
828 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
830 alkind ak = sRef_getAliasKind (ue->sref);
832 if (alkind_isRefCounted (ak))
834 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
838 if (alkind_isUnknown (ak))
840 exkind ek = sRef_getExKind (ue->sref);
842 if (exkind_isKnown (ek))
844 DPRINTF (("Setting imp dependent: %s",
845 uentry_unparseFull (ue)));
846 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
850 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
852 /* evans 2000-12-22 removed ctype_realType so it will
853 not apply to immutable abstract types. */
855 if (ctype_isVisiblySharable
856 (ctype_realType (ctype_getReturnType (ue->utype))))
858 if (uentryList_hasReturned (uentry_getParams (ue)))
864 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
866 ; /* Immutable objects are not shared. */
870 sRef_setAliasKind (ue->sref, AK_IMPONLY,
872 DPRINTF (("Ret imp only: %s",
873 ctype_unparse (ctype_getReturnType (ue->utype))));
883 static /*@notnull@*/ uentry
884 uentry_makeFunctionAux (cstring n, ctype t,
886 /*@only@*/ globSet globs,
887 /*@only@*/ sRefSet mods,
888 /*@only@*/ warnClause warn,
889 /*@keep@*/ fileloc f, bool priv,
890 /*@unused@*/ bool isForward)
892 uentry e = uentry_alloc ();
895 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
897 DPRINTF (("Make function: %s", n));
899 if (ctype_isFunction (t))
901 ret = ctype_getReturnType (t);
905 if (ctype_isKnown (t))
907 llbug (message ("not function: %s", ctype_unparse (t)));
914 if (fileloc_isSpec (f) || fileloc_isImport (f))
916 e->whereSpecified = f;
917 e->whereDeclared = fileloc_undefined;
921 e->whereSpecified = fileloc_undefined;
922 e->whereDeclared = f;
925 /* e->shallowCopy = FALSE; */
926 e->uname = cstring_copy (n);
928 e->storageclass = SCNONE;
930 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
932 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
934 if (ctype_isUA (ret))
936 sRef_setStateFromType (e->sref, ret);
941 e->uses = filelocList_new ();
943 e->hasNameError = FALSE;
947 e->info = (uinfo) dmalloc (sizeof (*e->info));
948 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
950 e->info->fcn->hasMods = sRefSet_isDefined (mods);
951 e->info->fcn->hasGlobs = globSet_isDefined (globs);
953 e->info->fcn->exitCode = XK_UNKNOWN;
954 e->info->fcn->nullPred = qual_createUnknown ();
955 e->info->fcn->specialCode = SPC_NONE;
957 e->info->fcn->access = access;
958 e->info->fcn->globs = globs;
959 e->info->fcn->defparams = uentryList_undefined;
961 sRef_setDefined (e->sref, f);
962 e->whereDefined = fileloc_undefined;
964 e->info->fcn->mods = sRefSet_undefined;
965 e->info->fcn->specclauses = NULL;
968 e->info->fcn->preconditions = NULL;
972 e->info->fcn->postconditions = NULL;
975 checkGlobalsModifies (e, mods);
976 e->info->fcn->mods = mods;
981 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
983 functionClauseList_elements (clauses, el)
985 DPRINTF (("Reflect clause: %s on %s",
986 functionClause_unparse (el), uentry_getName (ue)));
988 if (functionClause_isNoMods (el))
990 modifiesClause mel = functionClause_getModifies (el);
992 if (uentry_hasGlobs (ue))
997 ("No globals and modifies inconsistent to globals clause for %q: %q",
999 globSet_unparse (uentry_getGlobs (ue))),
1000 modifiesClause_getLoc (mel));
1004 if (uentry_hasMods (ue))
1009 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1010 uentry_getName (ue),
1011 sRefSet_unparse (uentry_getMods (ue))),
1012 modifiesClause_getLoc (mel));
1015 uentry_setGlobals (ue, globSet_undefined);
1016 uentry_setModifies (ue, sRefSet_undefined);
1018 else if (functionClause_isGlobals (el))
1020 globalsClause glc = functionClause_getGlobals (el);
1022 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1023 globalsClause_unparse (glc)));
1025 if (uentry_hasGlobs (ue))
1030 ("Multiple globals clauses for %q: %q",
1031 uentry_getName (ue),
1032 globalsClause_unparse (glc)),
1033 globalsClause_getLoc (glc));
1034 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1038 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1041 else if (functionClause_isModifies (el))
1043 modifiesClause mlc = functionClause_getModifies (el);
1045 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1047 if (uentry_hasMods (ue))
1055 ("Multiple modifies clauses for %s: %s",
1056 uentry_getName (ue),
1057 modifiesClause_unparse (mlc)),
1058 modifiesClause_getLoc (mlc)))
1060 llhint (message ("Previous modifies clause: ",
1061 sRefSet_unparse (uentry_getMods (ue))));
1067 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1071 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1074 else if (functionClause_isEnsures (el))
1076 functionConstraint cl = functionClause_takeEnsures (el);
1077 DPRINTF (("Setting post: %s / %s",
1078 uentry_unparse (ue), functionConstraint_unparse (cl)));
1079 uentry_setPostconditions (ue, cl);
1081 else if (functionClause_isRequires (el))
1083 functionConstraint cl = functionClause_takeRequires (el);
1084 uentry_setPreconditions (ue, cl);
1086 else if (functionClause_isState (el))
1088 stateClause sc = functionClause_takeState (el);
1090 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1092 sRefSet rfs = stateClause_getRefs (sc);
1094 sRefSet_elements (rfs, s)
1096 if (sRef_isParam (s))
1099 ** Can't use requires on parameters
1103 (FLG_ANNOTATIONERROR,
1104 message ("Requires clauses for %q concerns parameters %q should be "
1105 "a parameter annotation instead: %q",
1106 uentry_unparse (ue),
1108 stateClause_unparse (sc)),
1109 stateClause_loc (sc));
1111 } end_sRefSet_elements ;
1114 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1115 uentry_addStateClause (ue, sc);
1117 else if (functionClause_isWarn (el))
1119 warnClause wc = functionClause_takeWarn (el);
1120 uentry_addWarning (ue, wc);
1124 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1126 } end_functionClauseList_elements ;
1128 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1129 stateClauseList_checkAll (ue);
1132 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1134 bool leaveFunc = FALSE;
1136 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1137 typeId_invalid, globSet_undefined,
1138 sRefSet_undefined, warnClause_undefined,
1141 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1144 ** This makes parameters names print out correctly.
1145 ** (But we might be a local variable declaration for a function type...)
1148 if (context_inFunctionLike ())
1150 DPRINTF (("Header: %s / %s",
1151 uentry_unparse (context_getHeader ()),
1152 idDecl_unparse (id)));
1156 context_enterFunctionDeclaration (ue);
1160 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1161 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1162 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1163 reflectImplicitFunctionQualifiers (ue, FALSE);
1164 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1165 uentry_reflectClauses (ue, idDecl_getClauses (id));
1166 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1168 if (!uentry_isStatic (ue)
1169 && cstring_equalLit (ue->uname, "main"))
1171 ctype typ = ue->utype;
1175 llassert (ctype_isFunction (typ));
1177 retval = ctype_getReturnType (typ);
1179 if (!ctype_isInt (retval))
1183 message ("Function main declared to return %s, should return int",
1184 ctype_unparse (retval)),
1185 uentry_whereDeclared (ue));
1188 args = ctype_argsFunction (typ);
1190 if (uentryList_isMissingParams (args)
1191 || uentryList_size (args) == 0)
1197 if (uentryList_size (args) != 2)
1201 message ("Function main declared with %d arg%&, "
1202 "should have 2 (int argc, char *argv[])",
1203 uentryList_size (args)),
1204 uentry_whereLast (ue));
1208 uentry arg = uentryList_getN (args, 0);
1209 ctype ct = uentry_getType (arg);
1211 if (!ctype_isInt (ct))
1215 message ("Parameter 1, %q, of function main declared "
1216 "with type %t, should have type int",
1217 uentry_getName (arg), ct),
1218 uentry_whereDeclared (arg));
1221 arg = uentryList_getN (args, 1);
1222 ct = uentry_getType (arg);
1224 if (ctype_isArrayPtr (ct)
1225 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1226 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1234 message ("Parameter 2, %q, of function main declared "
1235 "with type %t, should have type char **",
1236 uentry_getName (arg), ct),
1237 uentry_whereDeclared (arg));
1245 context_exitFunctionDeclaration ();
1251 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1253 alkind ak = sRef_getAliasKind (e->sref);
1255 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1256 && context_getFlag (FLG_PARAMIMPTEMP))
1258 exkind ek = sRef_getExKind (e->sref);
1260 if (exkind_isKnown (ek))
1262 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1263 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1264 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1268 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1269 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1274 static /*@only@*/ /*@notnull@*/ uentry
1275 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1276 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1278 cstring pname = makeParam (n);
1281 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1282 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1284 cstring_free (pname);
1285 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1286 uentry_implicitParamAnnots (e);
1287 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1289 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1291 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1292 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1293 e->info->var->defstate = defstate;
1296 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1302 uentry_setRefCounted (uentry e)
1304 if (uentry_isValid (e))
1306 uentry_setAliasKind (e, AK_REFCOUNTED);
1307 sRef_storeState (e->sref);
1313 uentry_setStatic (uentry c)
1315 if (uentry_isValid (c))
1317 alkind ak = sRef_getAliasKind (c->sref);
1318 c->storageclass = SCSTATIC;
1320 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1322 if (!alkind_isUnknown (ak)
1323 && !alkind_isStatic (ak))
1325 if (!(ctype_isRealPointer (uentry_getType (c)))
1326 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1327 && !alkind_isRefCounted (ak))
1329 if (alkind_isImplicit (ak)
1330 && alkind_isDependent (ak)
1331 && ctype_isArray (uentry_getType (c)))
1333 ; /* no error for observer arrays */
1339 message ("Static storage %q declared as %s",
1341 alkind_unparse (ak)),
1342 uentry_whereDeclared (c));
1348 if (alkind_isUnknown (ak)
1349 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1350 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1352 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1353 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1361 uentry_setExtern (uentry c)
1363 if (uentry_isValid (c))
1364 c->storageclass = SCEXTERN;
1368 uentry_setParamNo (uentry ue, int pno)
1370 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1371 sRef_setParamNo (ue->sref, pno);
1375 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1377 sRefSet_allElements (sr, el)
1379 sRef base = sRef_getRootBase (el);
1381 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1382 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1384 if (!globSet_member (ue->info->fcn->globs, base))
1386 if (uentry_hasGlobs (ue)
1387 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1390 (FLG_WARNMISSINGGLOBALS,
1392 ("Modifies list for %q uses global %q, "
1393 "not included in globals list.",
1394 uentry_getName (ue),
1395 sRef_unparse (base)),
1396 uentry_whereLast (ue)))
1398 uentry_showWhereSpecified (ue);
1402 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1404 if (sRef_isFileStatic (base))
1406 context_recordFileGlobals (ue->info->fcn->globs);
1410 } end_sRefSet_allElements;
1414 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1416 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1420 uentry_fixupSref (uentry ue)
1424 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1429 sr = uentry_getSref (ue);
1431 sRef_resetState (sr);
1432 sRef_clearDerived (sr);
1434 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1435 llassert (sRef_isValid (sr));
1437 if (uentry_isVariable (ue))
1439 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1440 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1441 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1445 static void uentry_addStateClause (uentry ue, stateClause sc)
1448 ** Okay to allow multiple clauses of the same kind.
1449 */ /*@i834 is this true?@*/
1451 ue->info->fcn->specclauses =
1452 stateClauseList_add (ue->info->fcn->specclauses, sc);
1454 /* Will call checkAll to check later... */
1457 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1459 llassert (uentry_isFunction (ue));
1460 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1462 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1463 ue->info->fcn->specclauses = clauses;
1464 stateClauseList_checkAll (ue);
1465 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1469 ** Used for @modifies@ @endmodifies@ syntax.
1471 ** If ue is specified, sr must contain *only*:
1473 ** o file static globals
1474 ** o sRef's derived from modifies spec (i.e., more specific than
1475 ** what was specified)
1477 ** Otherwise, if sr has modifies it must match sr.
1479 ** If it doesn't have modifies, set them to sr.
1483 uentry_checkModifiesContext (void)
1485 if (sRef_modInFunction ())
1489 ("Modifies list not in function context. "
1490 "A modifies list can only appear following the parameter list "
1491 "in a function declaration or header."));
1500 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1502 if (!uentry_checkModifiesContext ())
1508 if (uentry_isValid (ue))
1510 if (uentry_isIter (ue))
1512 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1513 ue->info->iter->mods = sr;
1517 uentry_convertVarFunction (ue);
1518 llassertfatal (uentry_isFunction (ue));
1519 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1521 ue->info->fcn->mods = sr;
1522 ue->info->fcn->hasMods = TRUE;
1524 checkGlobalsModifies (ue, sr);
1527 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1529 ue->info->fcn->hasGlobs = TRUE;
1532 if (sRefSet_hasStatic (ue->info->fcn->mods))
1534 context_recordFileModifies (ue->info->fcn->mods);
1544 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1547 ** Function already has one modifies clause (possibly from
1548 ** a specification).
1551 if (!uentry_checkModifiesContext ())
1556 llassert (uentry_isValid (ue));
1558 if (uentry_isIter (ue))
1560 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1564 llassertfatal (uentry_isFunction (ue));
1565 llassert (ue->info->fcn->hasMods);
1567 checkGlobalsModifies (ue, sr);
1568 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1570 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1572 ue->info->fcn->hasGlobs = TRUE;
1576 if (sRefSet_hasStatic (ue->info->fcn->mods))
1578 context_recordFileModifies (ue->info->fcn->mods);
1582 bool uentry_hasWarning (uentry ue)
1584 return (uentry_isValid (ue)
1585 && warnClause_isDefined (ue->warn));
1588 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1590 llassert (warnClause_isUndefined (ue->warn));
1595 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1597 if (sRef_modInFunction ())
1600 (message ("Precondition list not in function context. "
1601 "A precondition list can only appear following the parameter list "
1602 "in a function declaration or header."));
1604 /*@-mustfree@*/ return; /*@=mustfree@*/
1607 if (uentry_isValid (ue))
1609 uentry_convertVarFunction (ue);
1610 llassertfatal (uentry_isFunction (ue));
1612 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1614 BADBRANCH; /* should conjoin constraints? */
1616 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1620 ue->info->fcn->preconditions = preconditions;
1625 llfatalbug ( (message("uentry_setPreconditions called with invalid uentry") ));
1634 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1636 if (sRef_modInFunction ())
1639 (message ("Postcondition list not in function context. "
1640 "A postcondition list can only appear following the parameter list "
1641 "in a function declaration or header."));
1643 /*@-mustfree@*/ return; /*@=mustfree@*/
1646 if (uentry_isValid (ue))
1648 uentry_convertVarFunction (ue);
1649 llassertfatal (uentry_isFunction (ue));
1651 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1653 ue->info->fcn->postconditions = postconditions;
1657 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1662 llfatalbug ( (message("uentry_setPostconditions called with invalid uentry") ));
1667 ** requires: new and old are functions
1671 checkGlobalsConformance (/*@notnull@*/ uentry old,
1672 /*@notnull@*/ uentry unew,
1673 bool mustConform, bool completeConform)
1675 bool hasInternalState = FALSE;
1677 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1679 if (globSet_isDefined (unew->info->fcn->globs))
1681 globSet_allElements (unew->info->fcn->globs, el)
1683 if (sRef_isFileStatic (el))
1685 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1687 if (sRef_isInvalid (sr))
1689 bool hasError = FALSE;
1691 if (!hasInternalState
1692 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1693 sRef_makeInternalState ()))
1694 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1695 sRef_makeSpecState ())))
1698 && !uentry_isStatic (old)
1701 message ("Globals list for %q includes internal state, %q, "
1702 "but %s without globals internalState.",
1703 uentry_getName (old),
1705 uentry_specOrDefName (old)),
1706 uentry_whereLast (unew)))
1708 uentry_showWhereSpecified (old);
1712 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1713 sRef_makeInternalState ());
1714 hasInternalState = TRUE;
1718 && fileloc_sameFile (uentry_whereDeclared (unew),
1719 uentry_whereDeclared (old)))
1724 message ("Function %q inconsistently %rdeclared (in "
1725 "same file) with file static global %q in "
1727 uentry_getName (unew),
1728 uentry_isDeclared (old),
1730 uentry_whereDeclared (unew)))
1732 uentry_showWhereSpecified (old);
1737 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1738 context_recordFileGlobals (old->info->fcn->globs);
1742 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1744 if (sRef_isInvalid (sr))
1749 message ("Function %q inconsistently %rdeclared with "
1750 "%q in globals list",
1751 uentry_getName (unew),
1752 uentry_isDeclared (old),
1754 uentry_whereDeclared (unew)))
1756 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1757 uentry_showWhereSpecified (old);
1762 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1768 ("Function %q global %q inconsistently "
1769 "%rdeclared as %qout global",
1770 uentry_getName (unew),
1772 uentry_isDeclared (old),
1773 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1774 uentry_whereDeclared (unew)))
1776 uentry_showWhereSpecified (old);
1781 } end_globSet_allElements ;
1783 if (completeConform)
1785 globSet_allElements (old->info->fcn->globs, el)
1787 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1789 if (sRef_isInvalid (sr))
1792 && uentry_isReallySpecified (old)
1795 message ("Function %q specified with %q in globals list, "
1796 "but declared without %q",
1797 uentry_getName (unew),
1800 uentry_whereDeclared (unew)))
1802 uentry_showWhereSpecified (old);
1805 } end_globSet_allElements;
1810 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1812 if (uentry_isReallySpecified (old)
1815 message ("%s %q specified with globals list, but "
1816 "declared with no globals",
1817 ekind_capName (unew->ukind),
1818 uentry_getName (unew)),
1819 uentry_whereDeclared (unew)))
1822 (message ("Specification globals: %q",
1823 globSet_unparse (old->info->fcn->globs)),
1824 uentry_whereSpecified (old));
1828 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1829 old->info->fcn->globs);
1834 ** new modifies list must be included by old modifies list.
1836 ** file static state may be added to new, if old has internal.
1840 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1841 bool mustConform, bool completeConform)
1844 bool changedMods = FALSE;
1845 bool modInternal = FALSE;
1847 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1849 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1850 newMods = unew->info->fcn->mods;
1852 if (sRefSet_isEmpty (newMods))
1854 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1855 && uentry_isReallySpecified (old))
1859 message ("%s %q specified with modifies clause, "
1860 "but declared with no modifies clause",
1861 ekind_capName (unew->ukind),
1862 uentry_getName (unew)),
1863 uentry_whereDeclared (unew)))
1865 llgenindentmsg (message ("Specification has modifies %q",
1866 sRefSet_unparse (old->info->fcn->mods)),
1867 uentry_whereSpecified (old));
1874 sRefSet_allElements (newMods, current)
1876 if (sRef_isValid (current))
1878 sRef rb = sRef_getRootBase (current);
1880 if (sRef_isFileStatic (rb))
1884 if (!sRefSet_isSameMember (old->info->fcn->mods,
1885 sRef_makeInternalState ())
1886 && !sRefSet_isSameMember (old->info->fcn->mods,
1887 sRef_makeSpecState ()))
1890 && !uentry_isStatic (old)
1894 ("Modifies list for %q includes internal state, "
1895 "but %s without modifies internal.",
1896 uentry_getName (old),
1897 uentry_specOrDefName (old)),
1898 uentry_whereLast (unew)))
1900 uentry_showWhereSpecified (old);
1903 old->info->fcn->mods =
1904 sRefSet_insert (old->info->fcn->mods,
1905 sRef_makeInternalState ());
1910 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1916 if (sRef_canModifyVal (current, old->info->fcn->mods))
1918 int size = sRefSet_size (old->info->fcn->mods);
1920 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1923 if (sRefSet_size (old->info->fcn->mods) != size)
1934 ("Modifies list for %q contains %q, not modifiable "
1936 uentry_getName (old),
1937 sRef_unparse (current),
1938 uentry_specDeclName (old)),
1939 uentry_whereLast (unew)))
1941 uentry_showWhereSpecified (old);
1946 } end_sRefSet_allElements;
1948 if (completeConform && uentry_isReallySpecified (old))
1950 sRefSet_allElements (old->info->fcn->mods, el)
1952 if (sRef_canModify (el, newMods))
1961 ("Specification modifies clause for %q contains %q, "
1962 "not included in declaration modifies clause",
1963 uentry_getName (old),
1965 uentry_whereLast (unew)))
1967 uentry_showWhereSpecified (old);
1970 } end_sRefSet_allElements ;
1974 ** Make sure file static elements will be removed.
1979 context_recordFileModifies (old->info->fcn->mods);
1984 uentry_checkMutableType (uentry ue)
1986 ctype ct = uentry_getType (ue);
1988 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1990 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
1992 voptgenerror (FLG_MUTREP,
1993 message ("Mutable abstract type %q declared without pointer "
1994 "indirection: %t (violates assignment semantics)",
1995 uentry_getName (ue), ct),
1996 uentry_whereDeclared (ue));
2001 uentry_setMutable (uentry e)
2003 llassert (uentry_isDatatype (e));
2004 e->info->datatype->mut = YES;
2008 uentry_checkIterArgs (uentry ue)
2010 bool hasYield = FALSE;
2013 llassert (uentry_isIter (ue));
2015 args = uentry_getParams (ue);
2017 uentryList_elements (args, el)
2019 sstate ds = uentry_getDefState (el);
2021 if (uentry_isYield (el))
2026 if (sstate_isUnknown (ds))
2028 uentry_setDefState (el, SS_DEFINED);
2034 } end_uentryList_elements;
2038 voptgenerror (FLG_HASYIELD,
2039 message ("Iterator %q declared with no yield parameters",
2040 uentry_getName (ue)),
2041 uentry_whereDeclared (ue));
2046 chkind_fromQual (qual qel)
2048 if (qual_isChecked (qel))
2052 else if (qual_isCheckMod (qel))
2056 else if (qual_isCheckedStrict (qel))
2058 return CH_CHECKEDSTRICT;
2060 else if (qual_isUnchecked (qel))
2062 return CH_UNCHECKED;
2067 /*@notreached@*/ return CH_UNKNOWN;
2072 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2074 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2076 if (!uentry_isRefCounted (ue))
2079 (FLG_ANNOTATIONERROR,
2080 message ("Reference counting qualifier %s used on non-reference "
2081 "counted storage: %q",
2083 uentry_unparse (ue)),
2084 uentry_whereLast (ue));
2088 alkind ak = alkind_fromQual (qel);
2090 uentry_setAliasKind (ue, ak);
2093 else if (qual_isRefCounted (qel))
2095 ctype ct = ctype_realType (uentry_getType (ue));
2098 if (ctype_isPointer (ct)
2099 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2101 /* check there is a refs field */
2102 uentryList fields = ctype_getFields (rt);
2103 uentry refs = uentry_undefined;
2105 uentryList_elements (fields, field)
2107 if (uentry_isRefsField (field))
2109 if (uentry_isValid (refs))
2112 (FLG_ANNOTATIONERROR,
2113 message ("Reference counted structure type %s has "
2114 "multiple refs fields: %q and %q",
2116 uentry_getName (refs),
2117 uentry_getName (field)),
2118 uentry_whereLast (field));
2123 } end_uentryList_elements;
2125 if (uentry_isInvalid (refs))
2129 message ("Reference counted structure type %s has "
2131 ctype_unparse (ct)),
2133 ("To count reference, the structure must have a field named "
2134 "refs of type int."),
2137 else if (!ctype_isInt (uentry_getType (refs)))
2140 (FLG_ANNOTATIONERROR,
2141 message ("Reference counted structure type %s refs field has "
2142 "type %s (should be int)", ctype_unparse (ct),
2143 ctype_unparse (uentry_getType (refs))),
2144 uentry_whereLast (refs));
2148 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2149 uentry_whereDeclared (ue));
2154 if ((ctype_isPointer (ct)
2155 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2156 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2158 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2159 uentry_whereDeclared (ue));
2164 (FLG_ANNOTATIONERROR,
2165 message ("Non-pointer to structure type %s declared with "
2166 "refcounted qualifier",
2167 ctype_unparse (ct)),
2168 uentry_whereLast (ue));
2172 else if (qual_isRefs (qel))
2174 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2176 uentry_setAliasKind (ue, AK_REFS);
2181 (FLG_ANNOTATIONERROR,
2182 message ("Refs qualifier used on non-structure field: %q",
2183 uentry_unparse (ue)),
2184 uentry_whereLast (ue));
2187 else if (qual_isAliasQual (qel))
2189 alkind ak = alkind_fromQual (qel);
2191 alkind oldak = uentry_getAliasKind (ue);
2192 ctype ut = uentry_getType (ue);
2194 if (alkind_isImplicit (ak)
2195 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2197 /* ignore the implied qualifier */
2201 if (uentry_isEitherConstant (ue))
2204 (FLG_ANNOTATIONERROR,
2205 message ("Alias qualifier %s used on constant: %q",
2206 alkind_unparse (ak), uentry_unparse (ue)),
2207 uentry_whereLast (ue));
2212 if (ctype_isFunction (ut))
2214 ut = ctype_getReturnType (ut);
2217 if (!(ctype_isVisiblySharable (ut)
2218 || ctype_isRealArray (ut)
2219 || ctype_isRealSU (ut)))
2221 if (!qual_isImplied (qel))
2224 (FLG_ANNOTATIONERROR,
2225 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2226 alkind_unparse (ak), ut, uentry_getName (ue)),
2227 uentry_whereLast (ue));
2234 if (uentry_isRefCounted (ue))
2236 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2237 || qual_isExposed (qel)
2238 || qual_isObserver (qel)))
2240 if (!qual_isImplied (qel))
2243 (FLG_ANNOTATIONERROR,
2245 ("Alias qualifier %s used on reference counted storage: %q",
2246 alkind_unparse (ak),
2247 uentry_unparse (ue)),
2248 uentry_whereLast (ue));
2256 if (qual_isRefQual (qel))
2259 (FLG_ANNOTATIONERROR,
2260 message ("Qualifier %s used on non-reference counted storage: %q",
2261 alkind_unparse (ak), uentry_unparse (ue)),
2262 uentry_whereLast (ue));
2271 uentry_setAliasKind (ue, ak);
2274 else if (qual_isNull (qel))
2276 if (uentry_isConstant (ue))
2280 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2281 uentry_whereDeclared (ue));
2285 uentry_setNullState (ue, NS_POSNULL);
2288 else if (qual_isRelNull (qel))
2290 uentry_setNullState (ue, NS_RELNULL);
2292 else if (qual_isNotNull (qel))
2294 uentry_setNullState (ue, NS_MNOTNULL);
2296 else if (qual_isAbstract (qel)
2297 || qual_isConcrete (qel))
2299 if (!uentry_isDatatype (ue))
2302 (FLG_ANNOTATIONERROR,
2303 message ("Qualifier %s used with non-datatype",
2304 qual_unparse (qel)),
2305 uentry_whereLast (ue));
2309 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2312 else if (qual_isMutable (qel))
2314 if (!uentry_isDatatype (ue))
2317 (FLG_ANNOTATIONERROR,
2318 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2319 uentry_whereLast (ue));
2323 if (!ynm_isOn (ue->info->datatype->mut))
2325 uentry_checkMutableType (ue);
2328 ue->info->datatype->mut = YES;
2331 else if (qual_isImmutable (qel))
2333 if (!uentry_isDatatype (ue))
2335 voptgenerror (FLG_ANNOTATIONERROR,
2336 message ("Qualifier %s used with non-datatype",
2337 qual_unparse (qel)),
2338 uentry_whereLast (ue));
2342 ue->info->datatype->mut = NO;
2345 else if (qual_isNullPred (qel))
2347 uentry_convertVarFunction (ue);
2349 if (uentry_isFunction (ue))
2351 ctype typ = uentry_getType (ue);
2352 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2354 if (ctype_isRealBool (rtype))
2356 uentryList pl = ctype_argsFunction (typ);
2358 if (uentryList_size (pl) == 1)
2360 ue->info->fcn->nullPred = qel;
2364 voptgenerror (FLG_ANNOTATIONERROR,
2365 message ("Qualifier %s used with function having %d "
2366 "arguments (should have 1)",
2368 uentryList_size (pl)),
2369 uentry_whereLast (ue));
2374 voptgenerror (FLG_ANNOTATIONERROR,
2375 message ("Qualifier %s used with function returning %s "
2376 "(should return bool)",
2378 ctype_unparse (rtype)),
2379 uentry_whereLast (ue));
2384 voptgenerror (FLG_ANNOTATIONERROR,
2385 message ("Qualifier %s used with non-function",
2386 qual_unparse (qel)),
2387 uentry_whereLast (ue));
2390 else if (qual_isExitQual (qel))
2392 exitkind exk = exitkind_fromQual (qel);
2394 if (uentry_isFunction (ue))
2396 if (exitkind_isKnown (ue->info->fcn->exitCode))
2398 voptgenerror (FLG_ANNOTATIONERROR,
2399 message ("Multiple exit qualifiers used on function %q: %s, %s",
2400 uentry_getName (ue),
2401 exitkind_unparse (ue->info->fcn->exitCode),
2402 exitkind_unparse (exk)),
2403 uentry_whereLast (ue));
2406 ue->info->fcn->exitCode = exk;
2410 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2412 uentry_makeVarFunction (ue);
2413 ue->info->fcn->exitCode = exk;
2417 voptgenerror (FLG_ANNOTATIONERROR,
2418 message ("Exit qualifier %s used with non-function (type %s)",
2420 ctype_unparse (uentry_getType (ue))),
2421 uentry_whereLast (ue));
2425 else if (qual_isMetaState (qel))
2427 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2429 if (annotationInfo_matchesContext (ainfo, ue))
2431 DPRINTF (("Reflecting %s on %s",
2432 annotationInfo_unparse (ainfo),
2433 uentry_unparseFull (ue)));
2435 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2436 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2437 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2442 (FLG_ANNOTATIONERROR,
2443 message ("Attribute annotation %s used in inconsistent context: %q",
2445 uentry_unparse (ue)),
2446 uentry_whereLast (ue)))
2448 /*@i! annotationInfo_showContextError (ainfo, ue); */
2454 if (qual_isCQual (qel))
2460 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2466 uentry_reflectQualifiers (uentry ue, qualList q)
2468 llassert (uentry_isValid (ue));
2470 DPRINTF (("Reflect qualifiers: %s / %s",
2471 uentry_unparseFull (ue), qualList_unparse (q)));
2473 qualList_elements (q, qel)
2475 if (qual_isStatic (qel))
2477 uentry_setStatic (ue);
2479 else if (qual_isUnused (qel))
2481 uentry_setUsed (ue, fileloc_undefined);
2483 else if (qual_isExternal (qel))
2485 fileloc_free (ue->whereDefined);
2486 ue->whereDefined = fileloc_createExternal ();
2488 else if (qual_isSef (qel))
2490 if (uentry_isVariable (ue))
2492 vkind vk = ue->info->var->kind;
2494 llassert (vk != VKREFPARAM);
2496 if (vk == VKYIELDPARAM)
2499 (FLG_ANNOTATIONERROR,
2500 message ("Qualifier sef cannot be used with %s: %q",
2501 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2502 uentry_unparse (ue)),
2503 uentry_whereLast (ue));
2505 else if (vk == VKRETPARAM)
2507 ue->info->var->kind = VKSEFRETPARAM;
2511 ue->info->var->kind = VKSEFPARAM;
2517 (FLG_ANNOTATIONERROR,
2518 message ("Qualifier sef is meaningful only on parameters: %q",
2519 uentry_unparse (ue)),
2520 uentry_whereLast (ue));
2523 else if (qual_isExtern (qel))
2525 ue->storageclass = SCEXTERN;
2527 else if (qual_isGlobalQual (qel)) /* undef, killed */
2529 DPRINTF (("Reflecting qual: %s / %s",
2530 qual_unparse (qel), uentry_unparse (ue)));
2532 if (uentry_isVariable (ue))
2534 sstate oldstate = ue->info->var->defstate;
2535 sstate defstate = sstate_fromQual (qel);
2538 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2539 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2541 defstate = SS_UNDEFKILLED;
2548 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2549 ue->info->var->defstate = defstate;
2554 (FLG_ANNOTATIONERROR,
2555 message ("Qualifier %s used on non-variable: %q",
2556 qual_unparse (qel), uentry_unparse (ue)),
2557 uentry_whereLast (ue));
2560 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2562 /* start modifications */
2563 else if( qual_isBufQualifier(qel) ) {
2564 ctype ct = ctype_realType(uentry_getType(ue));
2565 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2567 if( uentry_hasBufStateInfo(ue) ) {
2568 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2570 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2571 /* If formal func param */
2572 uentry_setNullTerminatedState(ue);
2573 uentry_setLen (ue, 1);
2574 uentry_setSize (ue, 1);
2576 sRef_setNullTerminatedState(uentry_getSref(ue));
2577 sRef_setLen (uentry_getSref(ue), 1);
2578 sRef_setSize (uentry_getSref(ue), 1);
2580 uentry_setPossiblyNullTerminatedState(ue);
2582 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2586 /* put other BufState Qualifiers here */
2588 cstring s = uentry_getName(ue);
2589 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2590 struct for identifier %s\n", s) );
2592 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2594 sRef retSref = uentry_getSref (ue);
2595 ctype retType = sRef_getType (retSref);
2597 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2598 sRef_setNullTerminatedState (retSref);
2604 message ("Qualifier %s used on non-pointer on \
2605 function return: %q", qual_unparse (qel),
2606 uentry_unparse (ue)));
2613 message ("Qualifier %s used on non-pointer: %q",
2614 qual_unparse (qel), uentry_unparse (ue)));
2616 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2618 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2620 ctype realType = ctype_realType (ue->utype);
2621 sstate defstate = sstate_fromQual (qel);
2623 if (ctype_isFunction (realType))
2625 realType = ctype_realType (ctype_getReturnType (realType));
2628 if (qual_isRelDef (qel))
2630 ; /* okay anywhere */
2634 if (!ctype_isAP (realType)
2635 && !ctype_isSU (realType)
2636 && !ctype_isUnknown (realType)
2637 && !ctype_isAbstract (ue->utype))
2640 (FLG_ANNOTATIONERROR,
2641 message ("Qualifier %s used on non-pointer or struct: %q",
2642 qual_unparse (qel), uentry_unparse (ue)),
2643 uentry_whereLast (ue));
2647 uentry_setDefState (ue, defstate);
2649 if (sRef_isStateSpecial (ue->sref)
2650 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2652 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2655 else if (qual_isYield (qel))
2657 if (uentry_isVariable (ue))
2659 ue->info->var->kind = VKYIELDPARAM;
2664 (FLG_ANNOTATIONERROR,
2665 message ("Qualifier %s used on non-iterator parameter: %q",
2666 qual_unparse (qel), uentry_unparse (ue)),
2667 uentry_whereLast (ue));
2670 else if (qual_isExQual (qel))
2672 exkind ek = exkind_fromQual (qel);
2673 ctype ut = uentry_getType (ue);
2675 DPRINTF (("Reflect ex qual: %s / %s",
2676 uentry_unparse (ue), exkind_unparse (ek)));
2678 if (ctype_isFunction (ut))
2680 ut = ctype_getReturnType (ut);
2683 if (!(ctype_isVisiblySharable (ut))
2684 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2685 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2687 if (!qual_isImplied (qel))
2689 if (ctype_isImmutableAbstract (ut)) {
2691 (FLG_REDUNDANTSHAREQUAL,
2692 message ("Qualifier %s used on unsharable storage type %t: %q",
2693 exkind_unparse (ek), ut, uentry_getName (ue)),
2694 uentry_whereLast (ue));
2697 (FLG_MISPLACEDSHAREQUAL,
2698 message ("Qualifier %s used on unsharable storage type %t: %q",
2699 exkind_unparse (ek), ut, uentry_getName (ue)),
2700 uentry_whereLast (ue));
2706 alkind ak = sRef_getAliasKind (ue->sref);
2708 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2709 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2711 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2713 if (!alkind_isTemp (ak))
2715 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2716 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2719 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2720 || alkind_isOwned (ak))
2728 message ("Exposure qualifier %s used on %s storage (should "
2729 "be dependent): %q",
2731 alkind_unparse (ak),
2732 uentry_unparse (ue)));
2736 else if (qual_isGlobCheck (qel))
2738 if (uentry_isVariable (ue))
2740 chkind ch = chkind_fromQual (qel);
2742 if (ue->info->var->checked != CH_UNKNOWN)
2744 if (ch == ue->info->var->checked)
2746 llerror (FLG_SYNTAX,
2747 message ("Redundant %s qualifier on %q",
2749 uentry_getName (ue)));
2753 llerror (FLG_SYNTAX,
2755 ("Contradictory %s and %s qualifiers on %q",
2757 checkedName (ue->info->var->checked),
2758 uentry_getName (ue)));
2762 ue->info->var->checked = ch;
2768 message ("Qualifier %s used with non-variable",
2769 qual_unparse (qel)));
2772 else if (qual_isReturned (qel))
2774 if (uentry_isVariable (ue))
2776 ue->info->var->kind = VKRETPARAM;
2780 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2781 qual_unparse (qel)));
2786 uentry_reflectOtherQualifier (ue, qel);
2789 sRef_storeState (ue->sref);
2790 } end_qualList_elements;
2794 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2798 uentry_isOnly (uentry ue)
2800 return (!uentry_isUndefined (ue)
2801 && uentry_isVariable (ue)
2802 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2806 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2808 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2809 sRef_setOrigAliasKind (ue->sref, ak);
2813 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2815 if (uentry_isVariable (ue))
2817 ue->info->var->nullstate = ns;
2820 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2824 uentry_isUnique (uentry ue)
2826 return (!uentry_isUndefined (ue)
2827 && uentry_isVariable (ue)
2828 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2832 uentry_isFileStatic (uentry ue)
2834 return (uentry_isStatic (ue)
2835 && (!uentry_isVariable (ue)
2836 || sRef_isFileStatic (uentry_getSref (ue))));
2840 uentry_isExported (uentry ue)
2842 if (uentry_isValid (ue))
2844 if (uentry_isVariable (ue))
2846 return (sRef_isRealGlobal (uentry_getSref (ue)));
2850 return !uentry_isStatic (ue);
2858 uentry_isNonLocal (uentry ue)
2860 return (uentry_isValid (ue) && uentry_isVariable (ue)
2861 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2865 uentry_isGlobalVariable (uentry ue)
2867 return (uentry_isValid (ue) && uentry_isVariable (ue)
2868 && sRef_isFileOrGlobalScope (ue->sref));
2872 uentry_isVisibleExternally (uentry ue)
2874 return (uentry_isValid (ue)
2875 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2876 || (!uentry_isStatic (ue)
2877 && (uentry_isFunction (ue)
2878 || uentry_isIter (ue)
2879 || uentry_isEndIter (ue)
2880 || uentry_isConstant (ue)
2881 || uentry_isDatatype (ue)
2882 || uentry_isAnyTag (ue)))));
2886 uentry_isPrintfLike (uentry ue)
2888 return (uentry_isFunction (ue)
2889 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2893 uentry_isScanfLike (uentry ue)
2895 return (uentry_isFunction (ue)
2896 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2900 uentry_isMessageLike (uentry ue)
2902 return (uentry_isFunction (ue)
2903 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2906 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2908 uentryList args = uentry_getParams (ue);
2910 if (!uentryList_isMissingParams (args))
2912 uentry last = uentry_undefined;
2914 uentryList_elements (args, current)
2916 if (uentry_isElipsisMarker (current))
2918 if (uentry_isUndefined (last))
2922 message ("Function %q is marked %s, but has no format "
2923 "string argument before elipsis",
2924 uentry_getName (ue),
2925 specCode_unparse (ue->info->fcn->specialCode)),
2926 uentry_whereLast (ue));
2927 ue->info->fcn->specialCode = SPC_NONE;
2931 ctype rt = ctype_realType (uentry_getType (last));
2933 if (!ctype_match (rt, ctype_string))
2937 /* wchar_t * is okay too */
2938 if (ctype_isAP (rt))
2940 ctype base = ctype_baseArrayPtr (rt);
2942 if (ctype_isArbitraryIntegral (base))
2952 message ("Function %q is marked %s, but the argument "
2953 "before the elipsis has type %s (should be char *)",
2954 uentry_getName (ue),
2955 specCode_unparse (ue->info->fcn->specialCode),
2956 ctype_unparse (uentry_getType (last))),
2957 uentry_whereLast (ue));
2959 ue->info->fcn->specialCode = SPC_NONE;
2966 } end_uentryList_elements ;
2970 message ("Function %q is marked %s, but has no elipsis parameter",
2971 uentry_getName (ue),
2972 specCode_unparse (ue->info->fcn->specialCode)),
2973 uentry_whereLast (ue));
2975 ue->info->fcn->specialCode = SPC_NONE;
2980 uentry_setPrintfLike (uentry ue)
2982 uentry_convertVarFunction (ue);
2983 llassertfatal (uentry_isFunction (ue));
2984 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2985 checkSpecialFunction (ue);
2989 uentry_setScanfLike (uentry ue)
2991 uentry_convertVarFunction (ue);
2992 llassertfatal (uentry_isFunction (ue));
2993 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2994 checkSpecialFunction (ue);
2998 uentry_setMessageLike (uentry ue)
3000 uentry_convertVarFunction (ue);
3001 llassertfatal (uentry_isFunction (ue));
3002 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3003 checkSpecialFunction (ue);
3007 uentry_isSpecialFunction (uentry ue)
3009 return (uentry_isFunction (ue)
3010 && (ue->info->fcn->specialCode != SPC_NONE));
3013 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3015 ctype ct = idDecl_getCtype (t);
3017 fileloc loc = setLocation ();
3018 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3019 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3021 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3022 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3023 uentry_implicitParamAnnots (ue);
3025 /* Parameter type [][] or [x][] is invalid */
3027 while (ctype_isFixedArray (base)) {
3028 base = ctype_baseArrayPtr (base);
3031 if (ctype_isIncompleteArray (base)) {
3032 base = ctype_baseArrayPtr (base);
3034 if (ctype_isArray (base)) {
3035 if (!uentry_hasName (ue)) {
3036 (void) optgenerror (FLG_INCOMPLETETYPE,
3037 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3039 ctype_unparse (ct)),
3040 uentry_whereLast (ue));
3042 (void) optgenerror (FLG_INCOMPLETETYPE,
3043 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3044 uentry_getName (ue),
3045 ctype_unparse (ct)),
3046 uentry_whereLast (ue));
3051 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3055 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3057 ctype ct = idDecl_getCtype (t);
3059 if (ctype_isFunction (ct))
3061 return (uentry_makeIdFunction (t));
3065 fileloc loc = setLocation ();
3066 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3068 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3070 if (!uentry_isExtern (ue))
3072 uentry_setDefined (ue, loc);
3080 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3082 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3090 /*@only@*/ /*@notnull@*/
3091 uentry uentry_makeConstantAux (cstring n, ctype t,
3092 /*@keep@*/ fileloc f, bool priv,
3093 /*@only@*/ multiVal m)
3095 uentry e = uentry_alloc ();
3098 e->uname = cstring_copy (n);
3100 e->storageclass = SCNONE;
3102 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3104 e->sref = sRef_makeConst (t);
3109 e->uses = filelocList_new ();
3110 e->isPrivate = priv;
3111 e->hasNameError = FALSE;
3113 e->info = (uinfo) dmalloc (sizeof (*e->info));
3114 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3115 e->info->uconst->access = typeIdSet_undefined;
3117 uentry_setSpecDef (e, f);
3119 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3121 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3124 uentry_setConstantValue (e, m);
3129 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3131 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
3134 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3136 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3137 idDecl_getCtype (t),
3140 llassert (fileloc_isUndefined (ue->whereDeclared));
3141 ue->whereDeclared = setLocation ();
3142 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3144 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3145 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3153 void uentry_setDefState (uentry ue, sstate defstate)
3155 if (uentry_isValid (ue))
3157 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3159 if (uentry_isVariable (ue))
3161 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3166 bool uentry_isCheckedUnknown (uentry ue)
3168 return (uentry_isVar (ue)
3169 && (ue->info->var->checked == CH_UNKNOWN));
3172 bool uentry_isCheckMod (uentry ue)
3174 return (uentry_isVar (ue)
3175 && (ue->info->var->checked == CH_CHECKMOD));
3178 bool uentry_isUnchecked (uentry ue)
3180 return (uentry_isVar (ue)
3181 && (ue->info->var->checked == CH_UNCHECKED));
3184 bool uentry_isChecked (uentry ue)
3186 return (uentry_isVar (ue)
3187 && (ue->info->var->checked == CH_CHECKED));
3190 bool uentry_isCheckedModify (uentry ue)
3192 return (uentry_isVar (ue)
3193 && (ue->info->var->checked == CH_CHECKED
3194 || ue->info->var->checked == CH_CHECKMOD
3195 || ue->info->var->checked == CH_CHECKEDSTRICT));
3198 bool uentry_isCheckedStrict (uentry ue)
3200 return (uentry_isVar (ue)
3201 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3204 void uentry_setUnchecked (uentry ue)
3206 llassert (uentry_isVar (ue));
3208 ue->info->var->checked = CH_UNCHECKED;
3211 void uentry_setChecked (uentry ue)
3213 llassert (uentry_isVar (ue));
3215 ue->info->var->checked = CH_CHECKED;
3218 void uentry_setCheckMod (uentry ue)
3220 llassert (uentry_isVar (ue));
3222 ue->info->var->checked = CH_CHECKMOD;
3225 void uentry_setCheckedStrict (uentry ue)
3227 llassert (uentry_isVar (ue));
3229 ue->info->var->checked = CH_CHECKEDSTRICT;
3232 static /*@only@*/ /*@notnull@*/
3233 uentry uentry_makeVariableAux (cstring n, ctype t,
3235 /*@exposed@*/ sRef s,
3236 bool priv, vkind kind)
3238 uentry e = uentry_alloc ();
3241 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3244 e->uname = cstring_copy (n);
3247 e->storageclass = SCNONE;
3249 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3256 e->uses = filelocList_new ();
3257 e->isPrivate = priv;
3258 e->hasNameError = FALSE;
3260 e->info = (uinfo) dmalloc (sizeof (*e->info));
3261 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3262 e->info->var->kind = kind;
3264 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3265 e->info->var->checked = CH_UNKNOWN;
3267 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3268 uentry_setSpecDef (e, f);
3269 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3271 if (ctype_isFunction (rt))
3273 rt = ctype_getReturnType (rt);
3276 if (ctype_isUA (rt))
3278 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3279 sRef_setStateFromType (e->sref, rt);
3282 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3283 e->info->var->defstate = sRef_getDefState (e->sref);
3284 e->info->var->nullstate = sRef_getNullState (e->sref);
3286 /* start modifications */
3287 /* This function sets the uentry for a pointer or array variable declaration,
3288 it allocates memory and sets the fields. We check if the type of the variable
3289 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3291 if( ctype_isArray (t) || ctype_isPointer(t)) {
3292 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3293 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3294 /*@access sRef@*/ /*i@222*/
3295 /* It probably isn't necessary to violate the abstraction here
3298 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
3301 e->info->var->bufinfo = NULL;
3303 /* end modification */
3309 uentry_isYield (uentry ue)
3311 return (uentry_isVariable (ue)
3312 && (ue->info->var->kind == VKYIELDPARAM
3313 || ue->info->var->kind == VKREFYIELDPARAM));
3317 uentry_isRefsField (uentry ue)
3319 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3322 /*@only@*/ /*@notnull@*/
3323 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3325 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3326 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3333 void uentry_makeVarFunction (uentry ue)
3340 llassert (uentry_isValid (ue));
3341 llassert (!sRef_modInFunction ());
3343 ak = sRef_getOrigAliasKind (ue->sref);
3344 ek = sRef_getOrigExKind (ue->sref);
3346 llassert (uentry_isVariable (ue));
3347 oldInfo = ue->info->var;
3349 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3352 ** expanded macro is marked used (until I write a pre-processor)
3355 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3358 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3359 ue->info->fcn->exitCode = XK_UNKNOWN;
3360 ue->info->fcn->nullPred = qual_createUnknown ();
3361 ue->info->fcn->specialCode = SPC_NONE;
3362 ue->info->fcn->access = typeIdSet_undefined;
3363 ue->info->fcn->hasGlobs = FALSE;
3364 ue->info->fcn->globs = globSet_undefined;
3365 ue->info->fcn->hasMods = FALSE;
3366 ue->info->fcn->mods = sRefSet_undefined;
3367 ue->info->fcn->specclauses = NULL;
3368 ue->info->fcn->defparams = uentryList_undefined;
3371 ue->info->fcn->preconditions = functionConstraint_undefined;
3375 ue->info->fcn->postconditions = functionConstraint_undefined;
3378 if (ctype_isFunction (ue->utype))
3380 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3384 ue->sref = sRef_makeType (ctype_unknown);
3387 if (sRef_isRefCounted (ue->sref))
3393 if (alkind_isUnknown (ak))
3395 if (exkind_isKnown (ek))
3397 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3398 ak = AK_IMPDEPENDENT;
3402 if (context_getFlag (FLG_RETIMPONLY))
3404 if (ctype_isFunction (ue->utype)
3405 && ctype_isVisiblySharable
3406 (ctype_realType (ctype_getReturnType (ue->utype))))
3408 if (uentryList_hasReturned (uentry_getParams (ue)))
3414 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3429 loc = ue->whereDeclared;
3431 sRef_setAliasKind (ue->sref, ak, loc);
3432 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3433 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3434 sRef_setExKind (ue->sref, ek, loc);
3436 if (oldInfo->kind == VKEXPMACRO)
3442 fileloc_free (ue->whereDefined);
3443 ue->whereDefined = fileloc_undefined;
3446 uvinfo_free (oldInfo);
3449 void uentry_makeConstantFunction (uentry ue)
3456 llassert (uentry_isValid (ue));
3457 llassert (!sRef_modInFunction ());
3459 ak = sRef_getOrigAliasKind (ue->sref);
3460 ek = sRef_getOrigExKind (ue->sref);
3462 llassert (uentry_isConstant (ue));
3463 oldInfo = ue->info->uconst;
3465 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3468 ** expanded macro is marked used (until I write a pre-processor)
3472 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3473 ue->info->fcn->exitCode = XK_UNKNOWN;
3474 ue->info->fcn->nullPred = qual_createUnknown ();
3475 ue->info->fcn->specialCode = SPC_NONE;
3476 ue->info->fcn->access = typeIdSet_undefined;
3477 ue->info->fcn->hasGlobs = FALSE;
3478 ue->info->fcn->globs = globSet_undefined;
3479 ue->info->fcn->hasMods = FALSE;
3480 ue->info->fcn->mods = sRefSet_undefined;
3481 ue->info->fcn->specclauses = NULL;
3482 ue->info->fcn->defparams = uentryList_undefined;
3485 ue->info->fcn->preconditions = functionConstraint_undefined;
3489 ue->info->fcn->postconditions = functionConstraint_undefined;
3493 if (ctype_isFunction (ue->utype))
3495 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3499 ue->sref = sRef_makeType (ctype_unknown);
3502 if (sRef_isRefCounted (ue->sref))
3508 if (alkind_isUnknown (ak))
3510 if (exkind_isKnown (ek))
3512 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3513 ak = AK_IMPDEPENDENT;
3517 if (context_getFlag (FLG_RETIMPONLY))
3519 if (ctype_isFunction (ue->utype)
3520 && ctype_isVisiblySharable
3521 (ctype_realType (ctype_getReturnType (ue->utype))))
3523 if (uentryList_hasReturned (uentry_getParams (ue)))
3529 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3544 loc = ue->whereDeclared;
3546 sRef_setAliasKind (ue->sref, ak, loc);
3547 sRef_setExKind (ue->sref, ek, loc);
3549 fileloc_free (ue->whereDefined);
3550 ue->whereDefined = fileloc_undefined;
3551 ucinfo_free (oldInfo);
3555 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3557 llassert (uentry_isValid (ue));
3559 if (uentry_isIter (ue))
3561 llassert (globSet_isUndefined (ue->info->iter->globs));
3562 ue->info->iter->globs = globs;
3566 uentry_convertVarFunction (ue);
3568 llassert (uentry_isFunction (ue));
3569 llassert (!ue->info->fcn->hasGlobs
3570 && globSet_isUndefined (ue->info->fcn->globs));
3572 ue->info->fcn->hasGlobs = TRUE;
3573 globSet_markImmutable (globs);
3574 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3579 /* ??? - evans 2001-09-09 not sure what's going on here...?
3580 if (globSet_hasStatic (globs))
3582 context_recordFileGlobals (globs);
3586 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3588 ue->info->fcn->hasMods = TRUE;
3592 void uentry_addAccessType (uentry ue, typeId tid)
3594 if (uentry_isFunction (ue))
3596 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3598 else if (uentry_isEitherConstant (ue))
3600 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3602 else if (uentry_isIter (ue))
3604 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3606 else if (uentry_isEndIter (ue))
3608 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3612 llbug (message ("no access for: %q", uentry_unparse (ue)));
3616 /*@only@*/ /*@notnull@*/ uentry
3617 uentry_makeFunction (cstring n, ctype t,
3619 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3620 /*@only@*/ warnClause warn,
3623 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3624 return (uentry_makeFunctionAux (n, t,
3625 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3626 : typeIdSet_single (access)),
3633 /*@notnull@*/ uentry
3634 uentry_makePrivFunction2 (cstring n, ctype t,
3636 globSet globs, sRefSet mods,
3639 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3644 /*@notnull@*/ uentry
3645 uentry_makeSpecFunction (cstring n, ctype t,
3647 /*@only@*/ globSet globs,
3648 /*@only@*/ sRefSet mods,
3651 uentry ue = uentry_makeFunctionAux (n, t, access,
3652 globs, mods, warnClause_undefined,
3655 uentry_setHasGlobs (ue);
3656 uentry_setHasMods (ue);
3658 reflectImplicitFunctionQualifiers (ue, TRUE);
3663 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3665 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3666 sRef_undefined, FALSE, VKEXPMACRO);
3668 uentry_setDefined (ue, f);
3672 /*@notnull@*/ /*@notnull@*/ uentry
3673 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3675 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3676 typeIdSet_singleOpt (access),
3677 globSet_undefined, sRefSet_undefined,
3678 warnClause_undefined,
3682 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3686 bool uentry_isForward (uentry e)
3688 if (uentry_isValid (e))
3690 ctype ct = uentry_getType (e);
3692 return (ctype_isUnknown (ct)
3693 || (ctype_isFunction (ct)
3694 && ctype_isUnknown (ctype_getReturnType (ct))));
3701 /*@notnull@*/ uentry
3702 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3704 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3705 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3709 /*@notnull@*/ uentry
3710 uentry_makeUnspecFunction (cstring n, ctype t,
3714 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3715 sRefSet_undefined, warnClause_undefined,
3718 reflectImplicitFunctionQualifiers (ue, TRUE);
3727 /* is exported for use by usymtab_interface */
3729 /*@notnull@*/ uentry
3730 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3731 fileloc f, bool priv)
3733 uentry e = uentry_alloc ();
3735 DPRINTF (("Make datatype: %s / %s",
3736 n, ctype_unparse (t)));
3738 /* e->shallowCopy = FALSE; */
3739 e->ukind = KDATATYPE;
3740 e->uname = cstring_copy (n);
3742 e->storageclass = SCNONE;
3743 e->sref = sRef_makeUnknown ();
3747 sRef_setStateFromType (e->sref, t);
3750 uentry_setSpecDef (e, f);
3752 e->warn = warnClause_undefined; /*@i634@*/
3753 e->uses = filelocList_new ();
3754 e->isPrivate = priv;
3755 e->hasNameError = FALSE;
3760 e->info = (uinfo) dmalloc (sizeof (*e->info));
3761 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3762 e->info->datatype->abs = abstract;
3763 e->info->datatype->mut = mut;
3764 e->info->datatype->type = ctype_undefined;
3766 if (uentry_isDeclared (e))
3768 uentry_setDefined (e, f);
3771 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3773 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3779 /*@notnull@*/ uentry
3780 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3782 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3785 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3787 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3788 ctype_bool, NO, abstract,
3789 fileloc_getBuiltin (),
3792 ret->info->datatype->type = ctype_bool;
3800 static /*@only@*/ /*@notnull@*/ uentry
3801 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3802 /*@only@*/ fileloc f)
3804 uentry e = uentry_alloc ();
3807 e->uname = cstring_copy (n);
3809 e->sref = sRef_makeUnknown ();
3810 e->storageclass = SCNONE;
3814 uentry_setSpecDef (e, f);
3816 e->warn = warnClause_undefined; /*@i452@*/
3817 e->uses = filelocList_new ();
3818 e->isPrivate = FALSE;
3819 e->hasNameError = FALSE;
3821 e->info = (uinfo) dmalloc (sizeof (*e->info));
3822 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3823 e->info->iter->access = access;
3824 e->info->iter->mods = sRefSet_undefined;
3825 e->info->iter->globs = globSet_undefined;
3827 uentry_checkIterArgs (e);
3831 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3833 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3836 static /*@notnull@*/ uentry
3837 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3839 uentry e = uentry_alloc ();
3841 /* e->shallowCopy = FALSE; */
3842 e->ukind = KENDITER;
3843 e->storageclass = SCNONE;
3844 e->uname = message ("end_%s", n);
3845 e->utype = ctype_unknown;
3846 e->sref = sRef_makeUnknown ();
3848 uentry_setSpecDef (e, f);
3853 e->uses = filelocList_new ();
3854 e->isPrivate = FALSE;
3855 e->hasNameError = FALSE;
3857 e->info = (uinfo) dmalloc (sizeof (*e->info));
3858 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3860 e->info->enditer->access = access;
3862 e->warn = warnClause_undefined; /*@i452@*/
3866 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3868 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3875 static /*@only@*/ /*@notnull@*/ uentry
3876 uentry_makeTagAux (cstring n, ctype t,
3877 /*@only@*/ fileloc fl,
3878 bool priv, ekind kind)
3880 uentry e = uentry_alloc ();
3882 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3884 llbuglit ("uentry_makeTagAux: not a tag type");
3888 /* e->shallowCopy = FALSE; */
3889 e->uname = cstring_copy (n);
3892 e->sref = sRef_makeUnknown ();
3893 e->storageclass = SCNONE;
3895 uentry_setSpecDef (e, fl);
3900 e->uses = filelocList_new ();
3901 e->isPrivate = priv;
3902 e->hasNameError = FALSE;
3904 e->info = (uinfo) dmalloc (sizeof (*e->info));
3905 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3906 e->info->datatype->abs = NO;
3907 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3908 e->info->datatype->type = t;
3909 e->warn = warnClause_undefined; /*@i452@*/
3911 if (uentry_isDeclared (e))
3913 uentry_setDefined (e, fl);
3919 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3921 cstring sname = makeStruct (n);
3922 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3924 cstring_free (sname);
3929 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3931 cstring sname = makeStruct (n);
3932 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3934 cstring_free (sname);
3939 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3941 cstring uname = makeUnion (n);
3942 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3944 cstring_free (uname);
3950 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3952 cstring ename = makeEnum (n);
3953 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3955 cstring_free (ename);
3961 uentry_makeUnionTagLoc (cstring n, ctype t)
3963 cstring uname = makeUnion (n);
3964 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3966 cstring_free (uname);
3971 uentry_makeEnumTagLoc (cstring n, ctype t)
3973 cstring ename = makeEnum (n);
3974 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3976 cstring_free (ename);
3981 uentry_isStructTag (uentry ue)
3983 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3987 uentry_isUnionTag (uentry ue)
3989 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3993 uentry_isEnumTag (uentry ue)
3995 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3999 uentry_isAnyTag (uentry ue)
4001 return (uentry_isStructTag (ue)
4002 || uentry_isUnionTag (ue)
4003 || uentry_isEnumTag (ue));
4006 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4008 extern void uentry_destroyMod (void)
4009 /*@globals killed emarker@*/ /*@modifies emarker@*/
4011 static bool wasDestroyed = FALSE;
4013 llassert (!wasDestroyed);
4015 if (emarker != NULL)
4017 uentry_reallyFree (emarker);
4020 wasDestroyed = TRUE;
4024 uentry_makeElipsisMarker (void)
4026 if (emarker == NULL)
4028 emarker = uentry_alloc ();
4030 emarker->ukind = KELIPSMARKER;
4031 emarker->uname = cstring_makeLiteral ("...");
4032 emarker->utype = ctype_elipsMarker;
4033 emarker->sref = sRef_undefined;
4034 emarker->storageclass = SCNONE;
4035 emarker->used = FALSE;
4036 emarker->lset = FALSE;
4037 emarker->info = NULL;
4039 uentry_setSpecDef (emarker, fileloc_undefined);
4040 emarker->uses = filelocList_new ();
4041 emarker->isPrivate = FALSE;
4042 emarker->hasNameError = FALSE;
4045 /*@ignore@*/ return (emarker); /*@end@*/
4053 uentry_equiv (uentry p1, uentry p2)
4055 if (uentry_compare (p1, p2) != 0)
4066 uentry_xcomparealpha (uentry *p1, uentry *p2)
4070 if ((res = uentry_compare (*p1, *p2)) == 0) {
4071 if ((*p1 != NULL) && (*p2 != NULL)) {
4072 res = cstring_compare ((*p1)->uname,
4081 uentry_xcompareuses (uentry *p1, uentry *p2)
4086 if (uentry_isValid (u1))
4088 if (uentry_isValid (u2))
4090 return (-1 * int_compare (filelocList_size (u1->uses),
4091 filelocList_size (u2->uses)));
4100 if (uentry_isValid (u2))
4112 uentry_compareStrict (uentry v1, uentry v2)
4114 COMPARERETURN (uentry_compare (v1, v2));
4116 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4118 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4119 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4120 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4127 uentry_compare (uentry u1, uentry u2)
4129 if (u1 == u2) return 0;
4131 if (uentry_isInvalid (u1)) return -1;
4132 if (uentry_isInvalid (u2)) return 1;
4134 INTCOMPARERETURN (u1->ukind, u2->ukind);
4135 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4136 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4137 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4143 /* bug detected by lclint:
4144 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4149 return (multiVal_compare (uentry_getConstantValue (u1),
4150 uentry_getConstantValue (u2)));
4154 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4156 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4157 uentry_accessType (u2)));
4158 return (uentryList_compareParams (uentry_getParams (u1),
4159 uentry_getParams (u2)));
4161 return (typeIdSet_compare (uentry_accessType (u1),
4162 uentry_accessType (u2)));
4165 ** Functions are never equivalent
4168 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4178 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4179 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4180 sRef_getOrigAliasKind (u2->sref)));
4181 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4182 sRef_getOrigExKind (u2->sref)));
4183 COMPARERETURN (generic_compare (u1->info->var->checked,
4184 u2->info->var->checked));
4185 COMPARERETURN (generic_compare (u1->info->var->defstate,
4186 u2->info->var->defstate));
4187 return (generic_compare (u1->info->var->nullstate,
4188 u2->info->var->nullstate));
4190 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4191 u2->info->datatype->type));
4192 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4193 u2->info->datatype->mut));
4194 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4203 ** all entries are: <type>[@<info>]*#<name>
4205 ** info depends on kind:
4209 advanceField (char **s)
4211 reader_checkChar (s, '@');
4215 advanceName (char **s)
4217 reader_checkChar (s, '#');
4221 vkind_fromInt (int i)
4223 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4225 llbuglit ("vkind_fromInt: out of range");
4232 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4233 typeIdSet access, nstate nullstate,
4234 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4236 uentry e = uentry_alloc ();
4241 e->sref = sRef_makeConst (ct);
4243 sRef_setNullState (e->sref, nullstate, loc);
4244 e->storageclass = SCNONE;
4246 if (fileloc_isSpec (loc))
4248 e->whereSpecified = loc;
4249 e->whereDeclared = fileloc_undefined;
4253 e->whereSpecified = fileloc_undefined;
4254 e->whereDeclared = loc;
4257 e->whereDefined = fileloc_undefined;
4258 e->uses = filelocList_new ();
4259 e->isPrivate = FALSE;
4260 e->hasNameError = FALSE;
4265 e->warn = warnClause_undefined; /*@i452@*/
4267 e->info = (uinfo) dmalloc (sizeof (*e->info));
4268 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4269 e->info->uconst->access = access;
4271 uentry_setConstantValue (e, m);
4272 sRef_storeState (e->sref);
4277 static /*@only@*/ uentry
4278 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4279 sstate defstate, nstate isnull, alkind aliased,
4280 exkind exp, chkind checked,
4281 /*@only@*/ fileloc loc)
4283 uentry e = uentry_alloc ();
4288 e->storageclass = SCNONE;
4290 e->sref = sRef_makeType (ct);
4291 sRef_setNullState (e->sref, isnull, loc);
4293 e->whereDefined = fileloc_undefined;
4295 if (fileloc_isSpec (loc))
4297 e->whereSpecified = loc;
4298 e->whereDeclared = fileloc_undefined;
4302 e->whereSpecified = fileloc_undefined;
4303 e->whereDeclared = loc;
4306 e->isPrivate = FALSE;
4307 e->hasNameError = FALSE;
4312 e->uses = filelocList_new ();
4313 e->warn = warnClause_undefined; /*@i452@*/
4315 e->info = (uinfo) dmalloc (sizeof (*e->info));
4316 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4317 e->info->var->kind = kind;
4318 e->info->var->checked = checked;
4319 e->info->var->defstate = defstate;
4321 sRef_setDefState (e->sref, defstate, loc);
4323 e->info->var->nullstate = sRef_getNullState (e->sref);
4325 sRef_setExKind (e->sref, exp, loc);
4326 sRef_setAliasKind (e->sref, aliased, loc);
4328 sRef_storeState (e->sref);
4330 /*DRL ADDED 9-1-2000 */
4331 e->info->var->bufinfo = NULL;
4336 static /*@only@*/ uentry
4337 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4338 ynm mut, ctype rtype, alkind ak, exkind exp,
4339 sstate defstate, nstate isnull,
4340 /*@only@*/ fileloc loc)
4342 uentry e = uentry_alloc ();
4344 e->ukind = KDATATYPE;
4345 /* e->shallowCopy = FALSE; */
4348 e->storageclass = SCNONE;
4349 e->sref = sRef_makeUnknown ();
4350 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4353 ** This is only setting null state. (I think?)
4356 if (ctype_isUA (ct))
4358 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4360 if (uentry_isValid (te))
4362 sRef_setStateFromUentry (e->sref, te);
4366 /* problem for recursive type definitions */
4370 sRef_setAliasKind (e->sref, ak, loc);
4371 sRef_setExKind (e->sref, exp, loc);
4373 sRef_setDefState (e->sref, defstate, loc);
4375 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4377 isnull = NS_ABSNULL;
4380 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4381 sRef_mergeNullState (e->sref, isnull);
4383 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4385 if (fileloc_isSpec (loc))
4387 e->whereSpecified = loc;
4388 e->whereDeclared = fileloc_undefined;
4392 e->whereSpecified = fileloc_undefined;
4393 e->whereDeclared = loc;
4396 e->isPrivate = FALSE;
4397 e->hasNameError = FALSE;
4399 e->warn = warnClause_undefined; /*@i452@*/
4403 e->uses = filelocList_new ();
4405 e->info = (uinfo) dmalloc (sizeof (*e->info));
4406 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4407 e->info->datatype->abs = abstract;
4408 e->info->datatype->mut = mut;
4409 e->info->datatype->type = rtype;
4411 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4412 sRef_storeState (e->sref);
4413 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4419 static void uentry_setHasGlobs (uentry ue)
4421 llassert (uentry_isFunction (ue));
4423 ue->info->fcn->hasGlobs = TRUE;
4426 static void uentry_setHasMods (uentry ue)
4428 llassert (uentry_isFunction (ue));
4430 ue->info->fcn->hasMods = TRUE;
4434 bool uentry_hasGlobs (uentry ue)
4436 if (uentry_isFunction (ue))
4438 return (ue->info->fcn->hasGlobs);
4444 bool uentry_hasStateClauseList (uentry ue)
4446 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4449 bool uentry_hasConditions (uentry ue)
4451 return (uentry_isFunction (ue)
4452 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4453 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4456 stateClauseList uentry_getStateClauseList (uentry ue)
4458 if (!uentry_isFunction (ue))
4460 llassert (uentry_isFunction (ue));
4461 return stateClauseList_undefined;
4464 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4465 return ue->info->fcn->specclauses;
4468 bool uentry_hasMods (uentry ue)
4470 if (uentry_isFunction (ue))
4472 return (ue->info->fcn->hasMods);
4479 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4481 bool hasGlobs, /*@only@*/ globSet globs,
4482 bool hasMods, /*@only@*/ sRefSet mods,
4483 alkind ak, exkind exp,
4484 sstate defstate, nstate isnull,
4488 /*@only@*/ stateClauseList specclauses,
4489 /*@only@*/ warnClause warnclause,
4490 /*@only@*/ fileloc loc)
4492 uentry e = uentry_alloc ();
4495 /* e->shallowCopy = FALSE; */
4499 e->storageclass = SCNONE;
4501 if (ctype_isFunction (ct))
4503 ret = ctype_getReturnType (ct);
4507 if (ctype_isKnown (ct))
4509 llbug (message ("not function: %s", ctype_unparse (ct)));
4512 ret = ctype_unknown;
4515 e->sref = sRef_makeType (ret);
4517 if (ctype_isUA (ret))
4519 sRef_setStateFromType (e->sref, ret);
4522 sRef_setDefined (e->sref, loc);
4523 sRef_setNullState (e->sref, isnull, loc);
4525 sRef_setAliasKind (e->sref, ak, loc);
4526 sRef_setExKind (e->sref, exp, loc);
4527 sRef_setDefState (e->sref, defstate, loc);
4529 e->whereSpecified = loc;
4530 e->whereDefined = fileloc_undefined;
4532 e->isPrivate = FALSE;
4533 e->hasNameError = FALSE;
4537 e->uses = filelocList_new ();
4538 e->warn = warnclause;
4540 e->info = (uinfo) dmalloc (sizeof (*e->info));
4541 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4543 e->info->fcn->exitCode = exitCode;
4544 e->info->fcn->specialCode = sCode;
4545 e->info->fcn->nullPred = nullPred;
4546 e->info->fcn->access = access;
4548 e->info->fcn->specclauses = specclauses;
4549 e->info->fcn->hasGlobs = hasGlobs;
4550 e->info->fcn->globs = globs;
4552 e->info->fcn->hasMods = hasMods;
4553 e->info->fcn->mods = mods;
4555 e->info->fcn->defparams = uentryList_undefined;
4556 e->whereDeclared = fileloc_undefined;
4558 sRef_storeState (e->sref);
4561 e->info->fcn->preconditions = NULL;
4565 e->info->fcn->postconditions = NULL;
4571 static /*@only@*/ uentry
4572 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4573 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4575 uentry e = uentry_alloc ();
4577 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4579 llbuglit ("uentry_makeTagBase: not a tag type");
4582 /* e->shallowCopy = FALSE; */
4586 e->sref = sRef_makeUnknown ();
4587 e->storageclass = SCNONE;
4589 if (fileloc_isSpec (loc))
4591 e->whereSpecified = loc;
4592 e->whereDeclared = fileloc_undefined;
4596 e->whereDeclared = loc;
4597 e->whereSpecified = fileloc_undefined;
4600 e->whereDefined = fileloc_undefined;
4602 e->isPrivate = FALSE;
4603 e->hasNameError = FALSE;
4607 e->uses = filelocList_new ();
4608 e->warn = warnClause_undefined; /*@i452@*/
4610 e->info = (uinfo) dmalloc (sizeof (*e->info));
4611 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4612 e->info->datatype->abs = NO;
4613 e->info->datatype->mut = MAYBE;
4614 e->info->datatype->type = rtype;
4616 sRef_storeState (e->sref);
4622 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4623 ctype ct, /*@only@*/ fileloc loc)
4625 uentry e = uentry_alloc ();
4627 /* e->shallowCopy = FALSE; */
4631 e->sref = sRef_makeUnknown ();
4632 e->storageclass = SCNONE;
4634 if (fileloc_isSpec (loc))
4636 e->whereSpecified = loc;
4637 e->whereDeclared = fileloc_undefined;
4641 e->whereDeclared = loc;
4642 e->whereSpecified = fileloc_undefined;
4645 e->whereDefined = fileloc_undefined;
4647 e->isPrivate = FALSE;
4648 e->hasNameError = FALSE;
4652 e->uses = filelocList_new ();
4653 e->warn = warnClause_undefined; /*@i452@*/
4655 e->info = (uinfo) dmalloc (sizeof (*e->info));
4656 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4657 e->info->iter->access = access;
4658 e->info->iter->mods = sRefSet_undefined;
4659 e->info->iter->globs = globSet_undefined;
4661 sRef_storeState (e->sref);
4666 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4667 /*@only@*/ fileloc loc)
4669 uentry e = uentry_alloc ();
4671 /* e->shallowCopy = FALSE; */
4672 e->ukind = KENDITER;
4673 e->storageclass = SCNONE;
4675 e->utype = ctype_unknown;
4676 e->sref = sRef_makeUnknown ();
4678 if (fileloc_isSpec (loc))
4680 e->whereSpecified = loc;
4681 e->whereDeclared = fileloc_undefined;
4685 e->whereDeclared = loc;
4686 e->whereSpecified = fileloc_undefined;
4689 e->whereDefined = fileloc_undefined;
4691 e->isPrivate = FALSE;
4692 e->hasNameError = FALSE;
4696 e->uses = filelocList_new ();
4697 e->warn = warnClause_undefined; /*@i452@*/
4699 e->info = (uinfo) dmalloc (sizeof (*e->info));
4700 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4701 e->info->enditer->access = access;
4702 sRef_storeState (e->sref);
4707 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4715 uentry_undump (ekind kind, fileloc loc, char **s)
4719 DPRINTF (("Uentry undump: %s", *s));
4723 reader_checkChar (s, '!');
4724 reader_checkChar (s, '.');
4725 ue = uentry_makeElipsisMarker ();
4729 ctype ct = ctype_undump (s);
4743 reader_checkChar (s, '|');
4745 if (reader_optCheckChar (s, '@'))
4747 tkind = vkind_fromInt (reader_getInt (s));
4748 reader_checkChar (s, '|');
4755 if (reader_optCheckChar (s, '$'))
4757 defstate = SS_UNKNOWN;
4758 isnull = NS_UNKNOWN;
4759 aliased = AK_IMPTEMP;
4761 checked = CH_UNKNOWN;
4763 else if (reader_optCheckChar (s, '&'))
4765 defstate = SS_DEFINED;
4766 isnull = NS_UNKNOWN;
4767 aliased = AK_IMPTEMP;
4769 checked = CH_UNKNOWN;
4771 else if (reader_optCheckChar (s, '^'))
4773 defstate = SS_UNKNOWN;
4774 isnull = NS_UNKNOWN;
4775 aliased = AK_IMPTEMP;
4777 checked = CH_UNKNOWN;
4781 defstate = sstate_fromInt (reader_getInt (s));
4782 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4783 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4785 if (reader_optCheckChar (s, '&'))
4788 checked = CH_UNKNOWN;
4792 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4793 advanceField (s); checked = (chkind) (reader_getInt (s));
4798 name = reader_getStringWord (s);
4800 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4802 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4803 isnull, aliased, exp,
4804 checked, fileloc_copy (loc));
4817 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4818 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4819 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4820 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4821 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4822 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4823 advanceField (s); rtype = ctype_undump (s);
4825 name = reader_getStringWord (s);
4826 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4827 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4828 aliased, exp, defstate, isnull,
4829 fileloc_copy (loc));
4846 stateClauseList specclauses = stateClauseList_undefined;
4847 warnClause warnclause = warnClause_undefined;
4849 if (reader_optCheckChar (s, '$'))
4851 defstate = SS_DEFINED;
4852 isnull = NS_UNKNOWN;
4853 exitCode = XK_UNKNOWN;
4855 nullPred = qual_createUnknown ();
4859 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4860 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4861 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4862 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4863 advanceField (s); nullPred = qual_undump (s);
4866 if (reader_optCheckChar (s, '$'))
4869 globs = globSet_undefined;
4871 mods = sRefSet_undefined;
4873 else if (reader_optCheckChar (s, '^'))
4876 globs = globSet_undefined;
4878 mods = sRefSet_undefined;
4882 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4883 advanceField (s); globs = globSet_undump (s);
4884 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4885 advanceField (s); mods = sRefSet_undump (s);
4888 if (reader_optCheckChar (s, '$'))
4895 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4896 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4899 advanceField (s); access = typeIdSet_undump (s);
4902 ** Optional clauses: Start with @<code>:
4905 while (reader_optCheckChar (s, '@'))
4907 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4909 reader_checkChar (s, ':');
4910 warnclause = warnClause_undump (s);
4912 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4914 reader_checkChar (s, ':');
4915 specclauses = stateClauseList_undump (s);
4923 advanceName (s); name = reader_getStringWord (s);
4925 ue = uentry_makeFunctionBase (name, ct, access,
4928 ak, exp, defstate, isnull,
4929 exitCode, specc, nullPred,
4932 fileloc_copy (loc));
4933 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4940 advanceField (s); access = typeIdSet_undump (s);
4941 advanceName (s); name = reader_getStringWord (s);
4943 ue = uentry_makeIterBase (name, access, ct,
4944 fileloc_copy (loc));
4951 advanceField (s); access = typeIdSet_undump (s);
4952 advanceName (s); name = reader_getStringWord (s);
4954 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4964 if (reader_optCheckChar (s, '$'))
4966 val = multiVal_undefined;
4967 access = typeIdSet_undefined;
4968 nullstate = NS_UNKNOWN;
4972 advanceField (s); val = multiVal_undump (s);
4973 advanceField (s); access = typeIdSet_undump (s);
4974 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4977 advanceName (s); name = reader_getStringWord (s);
4979 ue = uentry_makeConstantBase (name, ct, access,
4980 nullstate, fileloc_copy (loc), val);
4989 advanceField (s); rtype = ctype_undump (s);
4990 advanceName (s); name = reader_getStringWord (s);
4991 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4995 llcontbuglit ("uentry_undump: invalid");
4996 ue = uentry_undefined;
4999 llcontbuglit ("uentry_undump: elips marker");
5000 ue = uentry_undefined;
5009 uentry_dump (uentry v)
5011 return (uentry_dumpAux (v, FALSE));
5015 uentry_dumpParam (uentry v)
5017 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5018 ("dump: %s", uentry_unparseFull (v)));
5020 return (uentry_dumpAux (v, TRUE));
5024 uentry_dumpAux (uentry v, bool isParam)
5026 llassert (uentry_isValid (v));
5027 llassert (!uentry_isGlobalMarker (v));
5029 DPRINTF (("Dump uentry: [%p]", v));
5030 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5035 llcontbuglit ("uentry_dump: invalid entry");
5036 return cstring_undefined;
5038 return (message ("!."));
5042 vkind vk = v->info->var->kind;
5043 sstate dss = sRef_getDefState (v->sref);
5044 nstate nst = sRef_getNullState (v->sref);
5045 alkind alk = sRef_getAliasKind (v->sref);
5046 exkind exk = sRef_getExKind (v->sref);
5047 chkind chk = v->info->var->checked;
5049 DPRINTF (("Dumping var"));
5051 if (dss == SS_UNKNOWN
5052 && nst == NS_UNKNOWN
5053 && alk == AK_IMPTEMP
5054 && exk == XO_UNKNOWN
5055 && chk == CH_UNKNOWN)
5057 sdump = cstring_makeLiteral ("$");
5059 else if (dss == SS_DEFINED
5060 && nst == NS_UNKNOWN
5061 && alk == AK_IMPTEMP
5062 && exk == XO_UNKNOWN
5063 && chk == CH_UNKNOWN)
5065 sdump = cstring_makeLiteral ("&");
5067 else if (dss == SS_UNKNOWN
5068 && nst == NS_UNKNOWN
5069 && alk == AK_UNKNOWN
5070 && exk == XO_UNKNOWN
5071 && chk == CH_UNKNOWN)
5073 sdump = cstring_makeLiteral ("^");
5075 else if (exk == XO_UNKNOWN
5076 && chk == CH_UNKNOWN)
5078 sdump = message ("%d@%d@%d&",
5085 sdump = message ("%d@%d@%d@%d@%d",
5096 return (message ("%q|@%d|%q#%s",
5097 ctype_dump (v->utype),
5100 isParam ? cstring_undefined : v->uname));
5104 return (message ("%q|%q#%s",
5105 ctype_dump (v->utype),
5107 isParam ? cstring_undefined : v->uname));
5113 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5115 exkind_unparse (sRef_getExKind (v->sref)),
5116 ctype_unparse (v->utype), (int) v->utype));
5119 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5120 ctype_dump (v->utype),
5121 ynm_unparseCode (v->info->datatype->abs),
5122 ynm_unparseCode (v->info->datatype->mut),
5123 (int) sRef_getDefState (v->sref),
5124 (int) sRef_getNullState (v->sref),
5125 (int) sRef_getAliasKind (v->sref),
5126 (int) sRef_getExKind (v->sref),
5127 ctype_dump (v->info->datatype->type),
5131 cstring sdump, gdump, adump, xdump;
5132 alkind alk = sRef_getAliasKind (v->sref);
5133 exkind exk = sRef_getExKind (v->sref);
5135 if (sRef_getDefState (v->sref) == SS_DEFINED
5136 && !nstate_isKnown (sRef_getNullState (v->sref))
5137 && !exitkind_isKnown (v->info->fcn->exitCode)
5138 && v->info->fcn->specialCode == SPC_NONE
5139 && qual_isUnknown (v->info->fcn->nullPred))
5141 sdump = cstring_makeLiteral ("$");
5145 sdump = message ("@%d@%d@%d@%d@%x",
5146 (int) sRef_getDefState (v->sref),
5147 (int) sRef_getNullState (v->sref),
5148 (int) v->info->fcn->exitCode,
5149 (int) v->info->fcn->specialCode,
5150 qual_dump (v->info->fcn->nullPred));
5153 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5155 gdump = cstring_makeLiteral ("$");
5157 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5158 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5160 gdump = cstring_makeLiteral ("^");
5164 gdump = message ("@%s@%q@%s@%q",
5165 bool_dump (uentry_hasGlobs (v)),
5166 globSet_dump (uentry_getGlobs (v)),
5167 bool_dump (uentry_hasMods (v)),
5168 sRefSet_dump (uentry_getMods (v)));
5171 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5173 adump = cstring_makeLiteral ("$");
5177 adump = message ("@%d@%d", (int) alk, (int) exk);
5180 xdump = cstring_undefined;
5182 if (uentry_hasWarning (v))
5184 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5187 if (uentry_hasStateClauseList (v))
5189 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5192 return (message ("%q%q%q%q@%q%q#%s",
5193 ctype_dump (v->utype),
5197 typeIdSet_dump (uentry_accessType (v)),
5202 return (message ("%q@%q#%s",
5203 ctype_dump (v->utype),
5204 typeIdSet_dump (v->info->iter->access),
5207 return (message ("%q@%q#%s",
5208 ctype_dump (v->utype),
5209 typeIdSet_dump (uentry_accessType (v)),
5216 if (multiVal_isUnknown (uentry_getConstantValue (v))
5217 && typeIdSet_isEmpty (uentry_accessType (v))
5218 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5220 sdump = cstring_makeLiteral ("$");
5224 sdump = message ("@%q@%q@%d",
5225 multiVal_dump (uentry_getConstantValue (v)),
5226 typeIdSet_dump (uentry_accessType (v)),
5227 (int) sRef_getNullState (v->sref));
5230 return (message ("%q%q#%s",
5231 ctype_dump (v->utype),
5238 return (message ("%q@%q#%s",
5239 ctype_dump (v->utype),
5240 ctype_dump (v->info->datatype->type), v->uname));
5247 uentry_unparseAbbrev (uentry v)
5249 if (!uentry_isVariable (v))
5251 llcontbuglit ("uentry_unparseAbbrev: not variable");
5252 return uentry_unparse (v);
5255 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5259 uentry_unparse (uentry v)
5263 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5264 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5266 st = uentry_getName (v);
5268 if (cstring_isDefined (st))
5270 return (ctype_unparseDeclaration (v->utype, st));
5275 return (cstring_copy (ctype_unparse (v->utype)));
5280 uentry_unparseFull (uentry v)
5282 if (uentry_isUndefined (v))
5284 return (cstring_makeLiteral ("<undefined>"));
5290 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5291 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5292 ctype_unparse (v->utype),
5293 fileloc_unparse (uentry_whereSpecified (v)),
5294 fileloc_unparse (uentry_whereDeclared (v)),
5295 fileloc_unparse (uentry_whereDefined (v)));
5297 DPRINTF (("uentry: %s", res));
5299 if (uentry_isDatatype (v))
5301 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5304 (ctype_isDefined (v->info->datatype->type)
5305 ? v->info->datatype->type : ctype_unknown),
5306 ynm_unparse (v->info->datatype->mut),
5307 ynm_unparse (v->info->datatype->abs),
5308 sRef_unparseState (v->sref));
5310 else if (uentry_isFunction (v))
5312 res = message ("%q / sref: %q / mods: %q / "
5313 "globs: %q / clauses: %q / pre: %q / post: %q",
5315 sRef_unparseFull (v->sref),
5316 sRefSet_unparse (v->info->fcn->mods),
5317 globSet_unparse (v->info->fcn->globs),
5318 stateClauseList_unparse (v->info->fcn->specclauses),
5319 functionConstraint_unparse (v->info->fcn->preconditions),
5320 functionConstraint_unparse (v->info->fcn->postconditions));
5322 else if (uentry_isIter (v))
5324 res = message ("%q / sref: %q",
5326 sRef_unparseFull (v->sref));
5328 else if (uentry_isVariable (v))
5330 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5332 sRef_unparseFull (v->sref),
5333 (int) v->info->var->kind,
5334 (int) v->info->var->defstate,
5335 (int) v->info->var->nullstate,
5337 DPRINTF (("sref: [%p]", v->sref));
5338 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5339 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5341 else if (uentry_isConstant (v))
5343 res = message ("%q = %q",
5344 res, multiVal_unparse (uentry_getConstantValue (v)));
5348 res = message ("%q :: %q", res, uentry_unparse (v));
5355 bool uentry_hasAccessType (uentry e)
5357 if (uentry_isValid (e))
5362 return (!typeIdSet_isEmpty (e->info->iter->access));
5364 return (!typeIdSet_isEmpty (e->info->enditer->access));
5366 return (!typeIdSet_isEmpty (e->info->fcn->access));
5369 return (!typeIdSet_isEmpty (e->info->uconst->access));
5378 typeIdSet uentry_accessType (uentry e)
5380 if (uentry_isValid (e))
5385 return (e->info->iter->access);
5387 return (e->info->enditer->access);
5389 return (e->info->fcn->access);
5392 return (e->info->uconst->access);
5398 return typeIdSet_undefined;
5402 uentry_isVariable (uentry e)
5404 return (uentry_isVar (e));
5408 uentry_isSpecified (uentry e)
5410 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5414 uentry_isReallySpecified (uentry e)
5416 return (uentry_isValid (e)
5417 && fileloc_isRealSpec (e->whereSpecified));
5421 uentry_isVar (uentry e)
5423 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5427 uentry_isFakeTag (uentry e)
5429 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5433 uentry_isDatatype (uentry e)
5435 return (!uentry_isUndefined (e) &&
5436 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5437 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5441 uentry_setAbstract (uentry e)
5445 llassert (uentry_isDatatype (e)
5446 && (ynm_isMaybe (e->info->datatype->abs)));
5448 oldid = ctype_typeId (e->info->datatype->type);
5449 e->info->datatype->abs = YES;
5450 e->info->datatype->type = ctype_createAbstract (oldid);
5454 uentry_setConcrete (uentry e)
5456 llassert (uentry_isDatatype (e)
5457 && (ynm_isMaybe (e->info->datatype->abs)));
5459 e->info->datatype->abs = NO;
5463 uentry_isAbstractDatatype (uentry e)
5465 return (uentry_isDatatype (e)
5466 && (ynm_isOn (e->info->datatype->abs)));
5470 uentry_isMaybeAbstract (uentry e)
5472 return (uentry_isDatatype (e)
5473 && (ynm_isMaybe (e->info->datatype->abs)));
5477 uentry_isMutableDatatype (uentry e)
5479 bool res = uentry_isDatatype (e)
5480 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5486 uentry_isRefCountedDatatype (uentry e)
5488 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5492 uentry_isParam (uentry u)
5494 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5495 || u->info->var->kind == VKYIELDPARAM));
5499 uentry_isExpandedMacro (uentry u)
5501 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5505 uentry_isSefParam (uentry u)
5507 return (uentry_isVariable (u)
5508 && (u->info->var->kind == VKSEFPARAM
5509 || u->info->var->kind == VKREFSEFPARAM
5510 || u->info->var->kind == VKSEFRETPARAM
5511 || u->info->var->kind == VKREFSEFRETPARAM));
5515 uentry_isRefParam (uentry u)
5517 return (uentry_isVariable (u)
5518 && (u->info->var->kind == VKREFPARAM
5519 || u->info->var->kind == VKREFYIELDPARAM
5520 || u->info->var->kind == VKREFSEFPARAM
5521 || u->info->var->kind == VKREFSEFRETPARAM));
5525 uentry_isAnyParam (uentry u)
5527 return (uentry_isVariable (u)
5528 && ((u->info->var->kind == VKPARAM)
5529 || (u->info->var->kind == VKSEFPARAM)
5530 || (u->info->var->kind == VKYIELDPARAM)
5531 || (u->info->var->kind == VKRETPARAM)
5532 || (u->info->var->kind == VKSEFRETPARAM)));
5536 uentry_getDefState (uentry u)
5538 if (uentry_isValid (u))
5540 return (sRef_getDefState (u->sref));
5544 return (SS_UNKNOWN);
5549 uentry_isOut (uentry u)
5551 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5552 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5556 uentry_isPartial (uentry u)
5558 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5559 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5563 uentry_isStateSpecial (uentry u)
5565 return ((uentry_isVariable (u)
5566 && (u->info->var->defstate == SS_SPECIAL))
5567 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5570 exitkind uentry_getExitCode (uentry ue)
5572 if (uentry_isFunction (ue))
5574 return ue->info->fcn->exitCode;
5582 qual uentry_nullPred (uentry u)
5584 llassert (uentry_isRealFunction (u));
5586 if (uentry_isFunction (u))
5588 return (u->info->fcn->nullPred);
5592 return qual_createUnknown ();
5597 ** Note for variables, this is checking the declared state, not the current state.
5601 uentry_possiblyNull (uentry u)
5603 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5604 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5608 uentry_getAliasKind (uentry u)
5610 if (uentry_isValid (u))
5612 return (sRef_getAliasKind (uentry_getSref (u)));
5621 uentry_getExpKind (uentry u)
5623 if (uentry_isValid (u))
5625 return (sRef_getExKind (uentry_getSref (u)));
5634 uentry_isIter (uentry e)
5636 return (!uentry_isUndefined (e) && e->ukind == KITER);
5640 uentry_isEndIter (uentry e)
5642 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5646 uentry_isRealFunction (uentry e)
5648 return (uentry_isFunction (e) ||
5649 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5653 uentry_hasName (uentry e)
5655 if (uentry_isValid (e))
5657 cstring s = e->uname;
5659 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5660 || uentry_isFakeTag (e)));
5669 ** Returns true for fake tags.
5670 ** This is used for dumping the library
5673 bool uentry_hasRealName (uentry e)
5675 return (uentry_isValid (e)
5676 && cstring_isNonEmpty (e->uname)
5677 && !uentry_isGlobalMarker (e));
5681 /*@observer@*/ globSet
5682 uentry_getGlobs (uentry l)
5684 if (uentry_isInvalid (l))
5686 return globSet_undefined;
5689 if (l->ukind != KFCN)
5691 if (l->ukind != KITER && l->ukind != KENDITER)
5693 if (l->ukind == KVAR)
5695 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5697 ekind_unparse (l->ukind)));
5701 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5703 ekind_unparse (l->ukind)));
5706 return globSet_undefined;
5709 return l->info->fcn->globs;
5712 /*@observer@*/ sRefSet
5713 uentry_getMods (uentry l)
5715 llassert (uentry_isValid (l));
5717 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5719 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5720 return sRefSet_undefined;
5723 return l->info->fcn->mods;
5727 uentry_getKind (uentry e)
5729 llassert (uentry_isValid (e));
5734 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5736 llassert (uentry_isEitherConstant (e));
5737 return (sRef_getValue (e->sref));
5740 /*@observer@*/ uentryList
5741 uentry_getParams (uentry l)
5743 if (uentry_isInvalid (l)) return uentryList_undefined;
5750 ctype ct = l->utype;
5752 if (ctype_isFunction (ct))
5754 return (ctype_argsFunction (ct));
5758 return uentryList_undefined;
5763 ctype ct = l->utype;
5765 llassert (ctype_isFunction (ct));
5766 return (ctype_argsFunction (ct));
5773 /*@observer@*/ cstring
5774 uentry_rawName (uentry e)
5776 if (uentry_isValid (e))
5782 return cstring_undefined;
5787 uentry_getOptName (uentry e)
5789 cstring s = uentry_getName (e);
5791 if (cstring_isDefined (s))
5793 s = cstring_appendChar (s, ' ');
5800 uentry_getName (uentry e)
5802 cstring ret = cstring_undefined;
5804 if (uentry_isValid (e))
5806 if (uentry_isAnyTag (e))
5808 ret = fixTagName (e->uname);
5810 else if (uentry_isAnyParam (e))
5812 ret = cstring_copy (fixParamName (e->uname));
5816 ret = cstring_copy (e->uname);
5823 cstring uentry_observeRealName (uentry e)
5825 cstring ret = cstring_undefined;
5827 if (uentry_isValid (e))
5829 if (uentry_isAnyTag (e))
5831 if (isFakeTag (e->uname))
5833 ret = cstring_undefined;
5837 ret = plainTagName (e->uname);
5840 else if (uentry_isAnyParam (e))
5842 ret = fixParamName (e->uname);
5853 cstring uentry_getRealName (uentry e)
5855 if (uentry_isValid (e))
5857 if (uentry_isAnyTag (e))
5859 return (cstring_undefined);
5866 return cstring_undefined;
5869 ctype uentry_getType (uentry e)
5871 if (uentry_isValid (e))
5877 return ctype_unknown;
5881 fileloc uentry_whereLast (uentry e)
5885 if (uentry_isInvalid (e))
5887 return fileloc_undefined;
5890 loc = e->whereDefined;
5892 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5897 loc = uentry_whereDeclared (e);
5899 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5904 loc = uentry_whereSpecified (e);
5908 fileloc uentry_whereEither (uentry e)
5910 if (uentry_isInvalid (e)) return fileloc_undefined;
5912 if (fileloc_isDefined (e->whereDefined)
5913 && !fileloc_isExternal (e->whereDefined))
5915 return e->whereDefined;
5917 else if (fileloc_isDefined (e->whereDeclared))
5919 return e->whereDeclared;
5923 return e->whereSpecified;
5927 fileloc uentry_whereSpecified (uentry e)
5929 if (uentry_isInvalid (e)) return fileloc_undefined;
5931 return (e->whereSpecified);
5934 fileloc uentry_whereDefined (uentry e)
5936 if (uentry_isInvalid (e)) return fileloc_undefined;
5938 return (e->whereDefined);
5941 fileloc uentry_whereDeclared (uentry e)
5943 if (uentry_isInvalid (e)) return fileloc_undefined;
5945 return (e->whereDeclared);
5948 /*@observer@*/ fileloc
5949 uentry_whereEarliest (uentry e)
5951 if (uentry_isInvalid (e)) return fileloc_undefined;
5953 if (fileloc_isDefined (e->whereSpecified))
5955 return (e->whereSpecified);
5957 else if (fileloc_isDefined (e->whereDeclared))
5959 return (e->whereDeclared);
5963 return e->whereDefined;
5968 uentry_setFunctionDefined (uentry e, fileloc loc)
5970 if (uentry_isValid (e))
5972 llassert (uentry_isFunction (e));
5974 if (fileloc_isUndefined (e->whereDeclared))
5976 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5979 if (!fileloc_isDefined (e->whereDefined))
5981 e->whereDefined = fileloc_update (e->whereDefined, loc);
5987 uentry_setDeclDef (uentry e, fileloc f)
5989 uentry_setDeclared (e, f);
5991 if (!uentry_isFunction (e)
5992 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5994 uentry_setDefined (e, f);
5999 uentry_setDeclaredForce (uentry e, fileloc f)
6001 llassert (uentry_isValid (e));
6002 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6006 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6008 llassert (uentry_isValid (e));
6009 fileloc_free (e->whereDeclared);
6010 e->whereDeclared = f;
6014 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6018 llassert (uentry_isValid (e));
6019 oldloc = e->whereDeclared;
6021 if (fileloc_isDefined (oldloc))
6023 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6025 e->whereDeclared = f;
6026 fileloc_free (oldloc);
6035 e->whereDeclared = f;
6036 fileloc_free (oldloc);
6041 uentry_setDeclared (uentry e, fileloc f)
6045 llassert (uentry_isValid (e));
6046 oldloc = e->whereDeclared;
6048 if (fileloc_isDefined (oldloc))
6050 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6052 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6061 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6066 uentry_clearDefined (uentry e)
6068 if (uentry_isValid (e))
6070 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6075 uentry_setDefined (uentry e, fileloc f)
6079 llassert (uentry_isValid (e));
6080 oldloc = e->whereDefined;
6082 if (fileloc_isDefined (oldloc))
6084 if (fileloc_isLib (oldloc)
6085 || fileloc_isImport (oldloc)
6086 || fileloc_isBuiltin (oldloc)
6087 || fileloc_isPreproc (oldloc))
6089 e->whereDefined = fileloc_update (e->whereDefined, f);
6093 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6099 if (optgenerror (FLG_REDEF,
6100 message ("%s %q redefined",
6101 ekind_capName (e->ukind),
6102 uentry_getName (e)),
6105 llgenindentmsg (message ("Previous definition of %q",
6106 uentry_getName (e)),
6114 e->whereDefined = fileloc_update (e->whereDefined, f);
6119 uentry_isCodeDefined (uentry e)
6121 llassert (uentry_isValid (e));
6123 return (fileloc_isDefined (e->whereDefined));
6127 uentry_isDeclared (uentry e)
6129 if (uentry_isValid (e))
6131 return (fileloc_isDefined (e->whereDeclared));
6137 sRef uentry_getSref (uentry e)
6139 /* not true, used for functions too (but shouldn't be? */
6140 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6142 if (uentry_isInvalid (e)) return sRef_undefined;
6147 sRef uentry_getOrigSref (uentry e)
6149 /*@i523*/ /* evans 2001-09-09 - need to fix this
6150 if (uentry_isValid (e))
6152 if (uentry_isVariable (e))
6154 return e->info->var->origsref;
6158 sRef sr = sRef_copy (uentry_getSref (e));
6160 sRef_resetState (sr);
6161 sRef_clearDerived (sr);
6167 return sRef_undefined;
6171 if (uentry_isValid (e))
6173 sRef sr = sRef_copy (uentry_getSref (e));
6175 sRef_resetState (sr);
6176 sRef_clearDerived (sr);
6178 if (uentry_isVariable (e))
6180 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6181 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6188 return sRef_undefined;
6193 ** requires: uentry e is not in a hashed symbol table
6197 uentry_setName (uentry e, /*@only@*/ cstring n)
6199 llassert (uentry_isValid (e));
6201 cstring_free (e->uname);
6206 uentry_setType (uentry e, ctype t)
6208 if (uentry_isValid (e))
6211 sRef_setType (e->sref, t);
6216 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6219 ctype rettype = ctype_unknown;
6221 llassert (uentry_isValid (ue));
6223 uentry_convertVarFunction (ue);
6224 llassert (uentry_isFunction (ue));
6226 rct = ctype_realType (ue->utype);
6228 if (ctype_isFunction (rct))
6230 rettype = ctype_getReturnType (rct);
6233 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6237 uentry_setRefParam (uentry e)
6239 if (!uentry_isVar (e))
6241 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6245 if (e->info->var->kind == VKSEFPARAM)
6247 e->info->var->kind = VKREFSEFPARAM;
6249 else if (e->info->var->kind == VKSEFRETPARAM)
6251 e->info->var->kind = VKREFSEFRETPARAM;
6253 else if (e->info->var->kind == VKYIELDPARAM)
6255 e->info->var->kind = VKREFYIELDPARAM;
6259 e->info->var->kind = VKREFPARAM;
6265 uentry_setParam (uentry e)
6267 if (!uentry_isVar (e))
6269 if (uentry_isElipsisMarker (e))
6275 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6282 if (e->info->var->kind == VKYIELDPARAM
6283 || e->info->var->kind == VKSEFPARAM
6284 || e->info->var->kind == VKSEFRETPARAM)
6290 e->info->var->kind = VKPARAM;
6294 e->uname = makeParam (e->uname);
6295 cstring_free (oldname);
6300 uentry_setSref (uentry e, sRef s)
6302 if (uentry_isValid (e))
6304 if (sRef_isValid (e->sref))
6306 sRef_mergeStateQuietReverse (e->sref, s);
6310 e->sref = sRef_saveCopy (s);
6316 uentry_getAbstractType (uentry e)
6318 llassert (uentry_isDatatype (e));
6321 ** This assertion removed.
6322 ** Okay to have undefined type, for system types
6324 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6325 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6330 if (ctype_isUndefined (e->info->datatype->type))
6332 return ctype_unknown;
6336 ** Sadly, a kludge...
6339 if (ctype_isUserBool (e->info->datatype->type)) {
6343 return e->info->datatype->type;
6346 ctype uentry_getRealType (uentry e)
6349 typeId uid = USYMIDINVALID;
6351 if (uentry_isInvalid (e))
6353 return ctype_unknown;
6356 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6358 if (uentry_isAnyTag (e))
6363 if (uentry_isAbstractType (e))
6365 ct = uentry_getAbstractType (e);
6367 if (ctype_isManifestBool (ct)) {
6371 llassert (ctype_isUA (ct));
6373 uid = ctype_typeId (ct);
6375 if (!context_hasAccess (uid))
6381 ct = uentry_getType (e);
6383 /* if (ctype_isUserBool (ct)) return ct; */
6385 if (ctype_isManifestBool (ct)) {
6389 if (ctype_isUA (ct))
6391 usymId iid = ctype_typeId (ct);
6393 if (usymId_equal (iid, uid))
6395 llcontbug (message ("uentry_getRealType: recursive type! %s",
6396 ctype_unparse (ct)));
6401 /* evs 2000-07-25: possible infinite recursion ? */
6402 uentry ue2 = usymtab_getTypeEntry (iid);
6406 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6407 return ctype_unknown;
6410 return uentry_getRealType (ue2);
6419 ctype uentry_getForceRealType (uentry e)
6422 typeId uid = USYMIDINVALID;
6424 if (uentry_isInvalid (e))
6426 return ctype_unknown;
6429 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6431 if (uentry_isAnyTag (e))
6436 if (uentry_isAbstractType (e))
6438 ct = uentry_getAbstractType (e);
6439 llassert (ctype_isUA (ct));
6441 uid = ctype_typeId (ct);
6442 /* no check for access! */
6445 ct = uentry_getType (e);
6447 /* evs 2000-07-25 */
6448 /* if (ctype_isUserBool (ct)) return ct; */
6450 if (ctype_isManifestBool (ct)) {
6454 if (ctype_isUA (ct))
6456 usymId iid = ctype_typeId (ct);
6458 if (usymId_equal (iid, uid))
6460 llcontbug (message ("uentry_getRealType: recursive type! %s",
6461 ctype_unparse (ct)));
6466 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6475 uentry uentry_nameCopy (cstring name, uentry e)
6477 uentry enew = uentry_alloc ();
6479 llassert (uentry_isValid (e));
6481 /* enew->shallowCopy = FALSE; */
6482 enew->ukind = e->ukind;
6484 enew->utype = e->utype;
6485 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6486 enew->whereDefined = fileloc_copy (e->whereDefined);
6487 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6488 enew->sref = sRef_copy (e->sref);
6489 enew->used = e->used;
6491 enew->isPrivate = e->isPrivate;
6492 enew->hasNameError = FALSE;
6494 enew->uses = filelocList_new ();
6495 enew->warn = warnClause_undefined;
6497 enew->storageclass = e->storageclass;
6498 enew->info = uinfo_copy (e->info, e->ukind);
6504 uentry_setDatatype (uentry e, usymId uid)
6506 llassert (uentry_isDatatype (e));
6508 if (uentry_isAbstractType (e))
6510 e->info->datatype->type = ctype_createAbstract (uid);
6514 e->info->datatype->type = ctype_createUser (uid);
6519 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6520 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6523 llassert (uentry_isValid (e));
6525 if (fileloc_isSpec (f) || fileloc_isImport (f))
6527 e->whereSpecified = f;
6528 e->whereDeclared = fileloc_undefined;
6529 e->whereDefined = fileloc_undefined;
6533 e->whereSpecified = fileloc_undefined;
6534 e->whereDeclared = f;
6535 e->whereDefined = fileloc_undefined;
6538 llassert (fileloc_storable (f));
6542 ucinfo_free (/*@only@*/ ucinfo u)
6548 uvinfo_free (/*@only@*/ uvinfo u)
6550 /*drl7x added 6/29/01 */
6551 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6556 udinfo_free (/*@only@*/ udinfo u)
6562 ufinfo_free (/*@only@*/ ufinfo u)
6564 globSet_free (u->globs);
6565 sRefSet_free (u->mods);
6566 stateClauseList_free (u->specclauses);
6571 uiinfo_free (/*@only@*/ uiinfo u)
6577 ueinfo_free (/*@only@*/ ueinfo u)
6582 static /*@only@*/ ucinfo
6583 ucinfo_copy (ucinfo u)
6585 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6586 ret->access = u->access;
6590 static /*@only@*/ uvinfo
6591 uvinfo_copy (uvinfo u)
6593 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6595 ret->kind = u->kind;
6596 ret->nullstate = u->nullstate;
6597 ret->defstate = u->defstate;
6598 ret->checked = u->checked;
6600 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6602 /* drl added 07-02-001 */
6603 /* copy null terminated information */
6605 if (u->bufinfo != NULL)
6607 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6608 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6609 ret->bufinfo->size = u->bufinfo->size;
6610 ret->bufinfo->len = u->bufinfo->len;
6615 ret->bufinfo = NULL;
6621 static /*@only@*/ udinfo
6622 udinfo_copy (udinfo u)
6624 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6628 ret->type = u->type;
6633 static /*@only@*/ ufinfo
6634 ufinfo_copy (ufinfo u)
6636 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6638 ret->hasGlobs = u->hasGlobs;
6639 ret->hasMods = u->hasMods;
6640 ret->exitCode = u->exitCode;
6641 ret->specialCode = u->specialCode;
6642 ret->nullPred = u->nullPred;
6643 ret->access = u->access;
6644 ret->globs = globSet_newCopy (u->globs);
6645 ret->mods = sRefSet_newCopy (u->mods);
6646 ret->defparams = u->defparams;
6647 ret->specclauses = stateClauseList_copy (u->specclauses);
6649 ret->preconditions = functionConstraint_copy (u->preconditions);
6650 ret->postconditions = functionConstraint_copy (u->postconditions);
6655 static /*@only@*/ uiinfo
6656 uiinfo_copy (uiinfo u)
6658 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6660 ret->access = u->access;
6661 ret->globs = globSet_newCopy (u->globs);
6662 ret->mods = sRefSet_newCopy (u->mods);
6667 static /*@only@*/ ueinfo
6668 ueinfo_copy (ueinfo u)
6670 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6672 ret->access = u->access;
6677 uinfo_free (uinfo u, ekind kind)
6682 case KCONST: ucinfo_free (u->uconst); break;
6683 case KVAR: uvinfo_free (u->var); break;
6687 case KDATATYPE: udinfo_free (u->datatype); break;
6688 case KFCN: ufinfo_free (u->fcn); break;
6689 case KITER: uiinfo_free (u->iter); break;
6690 case KENDITER: ueinfo_free (u->enditer); break;
6691 case KELIPSMARKER: break;
6692 case KINVALID: break;
6698 static /*@only@*/ /*@null@*/ uinfo
6699 uinfo_copy (uinfo u, ekind kind)
6701 if (kind == KELIPSMARKER || kind == KINVALID)
6707 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6712 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6713 case KVAR: ret->var = uvinfo_copy (u->var); break;
6717 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6718 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6719 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6720 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6728 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6730 filelocList_free (e->uses);
6731 cstring_free (e->uname);
6733 uinfo_free (e->info, e->ukind);
6735 fileloc_free (e->whereSpecified);
6736 fileloc_free (e->whereDefined);
6737 fileloc_free (e->whereDeclared);
6739 warnClause_free (e->warn);
6745 extern void uentry_markOwned (/*@owned@*/ uentry u)
6747 sfreeEventually (u);
6751 uentry_free (/*@only@*/ uentry e)
6753 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6755 uentry_reallyFree (e);
6760 ** For uentry's in the global or file scope
6764 uentry_freeComplete (/*@only@*/ uentry e)
6766 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6768 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6769 /*@i@*/ sRef_free (e->sref);
6770 e->sref = sRef_undefined;
6771 uentry_reallyFree (e);
6776 ** requires old->kind != new->kind, old->uname = new->uname
6780 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6782 llassert (uentry_isValid (old));
6783 llassert (uentry_isValid (unew));
6785 if (uentry_isEitherConstant (unew)
6786 && (fileloc_isPreproc (uentry_whereDeclared (old))
6787 || ctype_isUnknown (old->utype))
6788 && !uentry_isSpecified (old))
6796 if (!uentry_isDeclared (old))
6798 if (uentry_isSpecified (old))
6800 if (uentry_isSpecified (unew))
6802 llbuglit ("Respecification!");
6804 else if (uentry_isDeclared (unew))
6808 message ("%s %q inconsistently declared as %s: %t",
6809 ekind_capName (old->ukind),
6810 uentry_getName (unew),
6811 ekind_unparseLong (unew->ukind),
6813 uentry_whereDeclared (unew)))
6815 uentry_showWhereLast (old);
6827 message ("%s %q inconsistently declared as %s: %t",
6828 ekind_capName (old->ukind),
6829 uentry_getName (unew),
6830 ekind_unparseLong (unew->ukind),
6832 uentry_whereDeclared (unew)))
6834 uentry_showWhereLast (old);
6840 llassert (uentry_isDeclared (unew));
6844 message ("%s %q inconsistently redeclared as %s",
6845 ekind_capName (old->ukind),
6846 uentry_getName (unew),
6847 ekind_unparseLong (unew->ukind)),
6848 uentry_whereDeclared (unew)))
6850 uentry_showWhereLast (old);
6856 uentry_updateInto (old, unew);
6860 ** def is the definition of spec, modifies spec
6862 ** reports any inconsistencies
6863 ** returns the summary of all available information
6864 ** if spec and def are inconsistent, def is returned
6868 uentry_showWhereLast (uentry spec)
6870 if (uentry_isValid (spec))
6872 if (fileloc_isDefined (spec->whereDefined)
6873 && !fileloc_isLib (spec->whereDefined)
6874 && !fileloc_isPreproc (spec->whereDefined))
6876 llgenindentmsg (message ("Previous definition of %q: %t",
6877 uentry_getName (spec),
6878 uentry_getType (spec)),
6879 uentry_whereDefined (spec));
6881 else if (uentry_isDeclared (spec))
6883 llgenindentmsg (message ("Previous declaration of %q: %t",
6884 uentry_getName (spec),
6885 uentry_getType (spec)),
6886 uentry_whereDeclared (spec));
6888 else if (uentry_isSpecified (spec))
6890 if (uentry_hasName (spec))
6892 llgenindentmsg (message ("Specification of %q: %t",
6893 uentry_getName (spec),
6894 uentry_getType (spec)),
6895 uentry_whereSpecified (spec));
6899 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6900 uentry_whereSpecified (spec));
6905 /* nothing to show */
6911 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6913 fileloc loc = uentry_whereDefined (ce);
6915 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6917 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6921 loc = uentry_whereSpecified (ce);
6923 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6925 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6930 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6932 if (uentry_isDeclared (spec))
6934 llgenindentmsg (message ("Previous declaration of %q: %q",
6935 uentry_getName (spec), extra),
6936 uentry_whereDeclared (spec));
6938 else if (uentry_isSpecified (spec))
6940 llgenindentmsg (message ("Specification of %q: %q",
6941 uentry_getName (spec), extra),
6942 uentry_whereSpecified (spec));
6946 cstring_free (extra);
6951 uentry_showWhereDeclared (uentry spec)
6953 if (uentry_isDeclared (spec))
6955 if (uentry_hasName (spec))
6957 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6958 uentry_whereDeclared (spec));
6962 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6965 else if (uentry_isSpecified (spec))
6967 if (uentry_hasName (spec))
6969 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6970 uentry_whereSpecified (spec));
6974 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6979 /* nothing to show */
6985 uentry_showWhereAny (uentry spec)
6987 if (uentry_isDeclared (spec))
6989 if (uentry_hasName (spec))
6991 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6992 uentry_whereDeclared (spec));
6996 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6999 else if (uentry_isSpecified (spec))
7001 if (uentry_hasName (spec))
7003 llgenindentmsg (message ("Specification of %q",
7004 uentry_getName (spec)),
7005 uentry_whereSpecified (spec));
7009 llgenindentmsg (cstring_makeLiteral ("Specification"),
7010 uentry_whereSpecified (spec));
7013 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7015 if (uentry_hasName (spec))
7017 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7018 uentry_whereDefined (spec));
7022 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7027 /* nothing to show */
7032 uentry_showWhereDefined (uentry spec)
7034 if (uentry_isCodeDefined (spec))
7036 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7037 uentry_whereDefined (spec));
7042 uentry_showWhereLastPlain (uentry spec)
7044 if (uentry_isDeclared (spec))
7046 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7047 uentry_whereDeclared (spec));
7049 else if (uentry_isSpecified (spec))
7051 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7052 uentry_whereSpecified (spec));
7060 uentry_showWhereLastVal (uentry spec, cstring val)
7062 if (uentry_isDeclared (spec))
7064 llgenindentmsg (message ("Previous declaration of %q: %s",
7065 uentry_getName (spec), val),
7066 uentry_whereDeclared (spec));
7068 else if (uentry_isSpecified (spec))
7070 llgenindentmsg (message ("Specification of %q: %s",
7071 uentry_getName (spec), val),
7072 uentry_whereSpecified (spec));
7080 uentry_showWhereSpecified (uentry spec)
7082 if (uentry_isSpecified (spec))
7084 if (uentry_hasName (spec))
7086 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7087 uentry_whereSpecified (spec));
7091 llgenindentmsg (cstring_makeLiteral ("Specification"),
7092 uentry_whereSpecified (spec));
7095 else if (uentry_isDeclared (spec))
7097 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7098 uentry_whereDeclared (spec));
7102 /* nothing to show */
7107 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7109 if (uentry_isSpecified (spec))
7111 if (uentry_hasName (spec))
7113 llgenindentmsg (message ("Specification of %q: %q",
7114 uentry_getName (spec), s),
7115 uentry_whereSpecified (spec));
7119 llgenindentmsg (message ("Specification: %q", s),
7120 uentry_whereSpecified (spec));
7123 else if (uentry_isDeclared (spec))
7125 llgenindentmsg (message ("Declaration of %q: %q",
7126 uentry_getName (spec), s),
7127 uentry_whereDeclared (spec));
7131 llgenindentmsg (message ("Previous: %q", s),
7132 uentry_whereLast (spec));
7141 checkStructConformance (uentry old, uentry unew)
7144 uentryList fold, fnew;
7147 ** requires: types of old and new are structs or unions
7150 llassert (uentry_isValid (old));
7151 llassert (uentry_isValid (unew));
7153 oldr = ctype_realType (old->utype);
7154 fold = ctype_getFields (oldr);
7156 newr = ctype_realType (unew->utype);
7157 fnew = ctype_getFields (newr);
7159 if (!uentryList_matchFields (fold, fnew))
7161 if (fileloc_equal (uentry_whereLast (old),
7162 uentry_whereLast (unew)))
7170 message ("%q %q %rdeclared with fields { %q }, %s "
7171 "with fields { %q }",
7172 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7173 uentry_getName (old),
7174 uentry_isDeclared (old),
7175 uentryList_unparseAbbrev (fnew),
7176 uentry_specOrDefName (old),
7177 uentryList_unparseAbbrev (fold)),
7178 uentry_whereDeclared (unew)))
7180 uentry_showWhereLastPlain (old);
7181 uentryList_showFieldDifference (fold, fnew);
7185 old->utype = unew->utype;
7190 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7193 ** requires old and new are enums
7196 ctype rold = ctype_realType (old->utype);
7197 ctype rnew = ctype_realType (unew->utype);
7198 enumNameList eold = ctype_elist (rold);
7199 enumNameList enew = ctype_elist (rnew);
7201 if (!enumNameList_match (eold, enew))
7205 message ("Enum %q declared with members { %q } but "
7206 "specified with members { %q }",
7207 uentry_getName (old),
7208 enumNameList_unparse (enew),
7209 enumNameList_unparse (eold)),
7210 uentry_whereDeclared (unew)))
7212 uentry_showWhereSpecified (old);
7213 old->utype = unew->utype;
7219 ** either oldCurrent or newCurrent may be undefined!
7223 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7224 uentry unew, uentry newCurrent, ctype newType,
7227 bool hasError = FALSE;
7229 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7231 if (uentry_hasName (newCurrent))
7233 hasError = optgenerror
7235 message ("Parameter %d, %q, of function %q has inconsistent type: "
7236 "declared %t, %s %t",
7237 paramno + 1, uentry_getName (newCurrent),
7238 uentry_getName (unew),
7239 newType, uentry_specOrDefName (old), oldType),
7240 uentry_whereDeclared (newCurrent));
7244 hasError = optgenerror
7246 message ("Parameter %d of function %q has inconsistent type: "
7247 "declared %t, %s %t",
7248 paramno + 1, uentry_getName (unew),
7249 newType, uentry_specOrDefName (old), oldType),
7250 uentry_whereDeclared (newCurrent));
7252 DPRINTF (("type: %s / %s",
7253 ctype_unparse (newType),
7254 ctype_unparse (ctype_realType (newType))));
7259 if (uentry_isDeclared (unew))
7261 hasError = optgenerror
7263 message ("Parameter %d of function %s has inconsistent type: "
7264 "declared %t, %s %t",
7265 paramno + 1, unew->uname,
7266 newType, uentry_specOrDefName (old), oldType),
7267 uentry_whereDeclared (unew));
7271 hasError = optgenerror
7273 message ("Parameter %d of function %s has inconsistent type: "
7274 "declared %t, %s %t",
7275 paramno + 1, unew->uname,
7276 newType, uentry_specOrDefName (old), oldType),
7277 uentry_whereDeclared (unew));
7283 DPRINTF (("Here: %s / %s",
7284 uentry_unparseFull (oldCurrent),
7285 uentry_unparseFull (newCurrent)));
7287 if (!uentry_isUndefined (oldCurrent))
7289 if (!uentry_isUndefined (newCurrent)
7290 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7292 uentry_showWhereLast (oldCurrent);
7296 uentry_showWhereLastPlain (old);
7299 uentry_setType (oldCurrent, newType);
7303 uentry_showWhereLastPlain (old);
7309 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7313 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7315 uentry_isDeclared (old),
7316 uentryList_size (uentry_getParams (unew)),
7317 uentry_specOrDefName (old),
7318 uentryList_size (uentry_getParams (old))),
7319 uentry_whereDeclared (unew)))
7321 uentry_showWhereLastPlain (old);
7326 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7330 message ("Function %s inconsistently %rdeclared to return %t",
7332 uentry_isDeclared (old),
7333 ctype_getReturnType (unew->utype)),
7334 uentry_whereDeclared (unew)))
7336 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7340 static cstring paramStorageName (uentry ue)
7342 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7345 static cstring fcnErrName (uentry ue)
7347 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7350 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7352 if (uentry_isVar (ue))
7354 return (checkedName (ue->info->var->checked));
7358 return (cstring_makeLiteralTemp ("<checked invalid>"));
7362 static cstring checkedName (chkind checked)
7366 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7367 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7368 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7369 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7370 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7376 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7381 if (uentry_isVar (unew))
7383 llassert (uentry_isVar (old));
7385 oldState = old->info->var->nullstate;
7386 newState = unew->info->var->nullstate;
7390 oldState = sRef_getNullState (old->sref);
7391 newState = sRef_getNullState (unew->sref);
7394 if (oldState == NS_ABSNULL)
7396 if (uentry_isVar (old))
7398 old->info->var->nullstate = newState;
7401 sRef_mergeNullState (old->sref, newState);
7403 else if (newState == NS_UNKNOWN)
7405 if (completeConform && newState != oldState
7406 && uentry_isReallySpecified (old))
7410 message ("%s %q specified as %s, but declared without %s qualifier",
7411 ekind_capName (unew->ukind),
7412 uentry_getName (unew),
7413 nstate_unparse (oldState),
7414 nstate_unparse (oldState)),
7415 uentry_whereDeclared (unew)))
7417 uentry_showWhereSpecified (old);
7421 if (uentry_isVar (unew))
7423 unew->info->var->nullstate = oldState;
7426 sRef_mergeNullState (unew->sref, oldState);
7428 else if (newState == NS_POSNULL)
7430 if (oldState == NS_MNOTNULL
7431 && (ctype_isUA (unew->utype)
7432 || (uentry_isFunction (unew)
7433 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7435 if (uentry_isVar (unew))
7437 unew->info->var->nullstate = oldState;
7440 sRef_mergeNullState (unew->sref, oldState);
7444 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7445 || oldState == NS_UNKNOWN)
7452 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7454 uentry_ekindName (unew),
7455 uentry_getName (unew),
7456 uentry_isDeclared (old),
7458 uentry_specOrDefName (old),
7459 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7460 uentry_whereDeclared (unew)))
7462 uentry_showWhereSpecified (old);
7467 if (uentry_isVar (old))
7469 old->info->var->nullstate = newState;
7472 sRef_mergeNullState (old->sref, newState);
7475 else if (newState == NS_MNOTNULL)
7477 if (oldState != NS_MNOTNULL)
7483 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7484 "%s without notnull qualifier",
7485 uentry_ekindName (unew),
7486 uentry_getName (unew),
7487 uentry_isDeclared (old),
7489 uentry_specOrDefName (old)),
7490 uentry_whereDeclared (unew)))
7492 uentry_showWhereSpecified (old);
7496 if (uentry_isVar (old))
7498 old->info->var->nullstate = newState;
7501 sRef_mergeNullState (old->sref, newState);
7506 if (uentry_isVar (unew))
7508 unew->info->var->nullstate = oldState;
7511 sRef_mergeNullState (unew->sref, oldState);
7516 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7517 bool mustConform, bool completeConform)
7523 if (uentry_isVar (old) && uentry_isVar (unew))
7525 oldState = old->info->var->defstate;
7526 newState = unew->info->var->defstate;
7531 oldState = sRef_getDefState (old->sref);
7532 newState = sRef_getDefState (unew->sref);
7535 if (newState != oldState
7536 && newState != SS_UNKNOWN
7537 && newState != SS_DEFINED)
7543 message ("%s %q inconsistently %rdeclared %s %s %s, "
7545 uentry_ekindName (unew),
7546 uentry_getName (unew),
7547 uentry_isDeclared (old),
7549 sstate_unparse (newState),
7550 paramStorageName (unew),
7551 uentry_specOrDefName (old),
7553 sstate_unparse (oldState),
7554 paramStorageName (unew)),
7555 uentry_whereDeclared (unew)))
7557 uentry_showWhereSpecified (old);
7561 if (vars) old->info->var->defstate = newState;
7562 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7567 && (newState != oldState) && (oldState != SS_DEFINED)
7568 && uentry_isReallySpecified (old))
7572 message ("%s %q specified as %s, but declared without %s qualifier",
7573 ekind_capName (unew->ukind),
7574 uentry_getName (unew),
7575 sstate_unparse (oldState),
7576 sstate_unparse (oldState)),
7577 uentry_whereDeclared (unew)))
7579 uentry_showWhereSpecified (old);
7583 if (vars) unew->info->var->defstate = oldState;
7584 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7589 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7590 bool mustConform, bool completeConform)
7595 oldKind = sRef_getAliasKind (old->sref);
7596 newKind = sRef_getAliasKind (unew->sref);
7598 if (alkind_isImplicit (newKind)
7599 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7601 if (completeConform && !alkind_equal (newKind, oldKind)
7602 && uentry_isReallySpecified (old))
7606 message ("%s %q specified as %s, but declared without "
7607 "explicit alias qualifier",
7608 ekind_capName (unew->ukind),
7609 uentry_getName (unew),
7610 alkind_unparse (oldKind)),
7611 uentry_whereDeclared (unew)))
7613 uentry_showWhereSpecified (old);
7618 ** This really shouldn't be necessary, but it is!
7619 ** Function params (?) use new here.
7622 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7626 if (alkind_isKnown (newKind))
7628 if (!alkind_equal (oldKind, newKind))
7630 if (alkind_isKnown (oldKind))
7635 message ("%s %q inconsistently %rdeclared %s %s storage, "
7637 uentry_ekindName (unew),
7638 uentry_getName (unew),
7639 uentry_isDeclared (old),
7641 alkind_unparse (newKind),
7642 uentry_specOrDefName (old),
7643 alkind_unparse (oldKind)),
7644 uentry_whereDeclared (unew)))
7646 uentry_showWhereSpecified (old);
7648 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7649 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7650 sRef_setAliasKind (old->sref, AK_ERROR,
7651 uentry_whereDeclared (unew));
7655 sRef_setAliasKind (old->sref, newKind,
7656 uentry_whereDeclared (unew));
7661 if (!(alkind_isImplicit (newKind)))
7664 !uentry_isFunction (unew) &&
7667 message ("%s %q inconsistently %rdeclared %s %s storage, "
7668 "implicitly %s as temp storage",
7669 uentry_ekindName (unew),
7670 uentry_getName (unew),
7671 uentry_isDeclared (old),
7673 alkind_unparse (newKind),
7674 uentry_specOrDefName (old)),
7675 uentry_whereDeclared (unew)))
7677 uentry_showWhereSpecified (old);
7681 sRef_setAliasKind (old->sref, newKind,
7682 uentry_whereDeclared (unew));
7684 else /* newKind is temp or refcounted */
7691 else /* newKind unknown */
7698 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7699 bool mustConform, bool completeConform)
7704 oldKind = sRef_getExKind (old->sref);
7705 newKind = sRef_getExKind (unew->sref);
7707 if (exkind_isKnown (newKind))
7709 if (oldKind != newKind)
7711 if (exkind_isKnown (oldKind))
7716 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7717 uentry_ekindName (unew),
7718 uentry_getName (unew),
7719 uentry_isDeclared (old),
7721 exkind_unparse (newKind),
7722 uentry_specOrDefName (old),
7723 exkind_unparse (oldKind)),
7724 uentry_whereDeclared (unew)))
7726 uentry_showWhereSpecified (old);
7729 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7736 message ("%s %q inconsistently %rdeclared %s %s, "
7737 "implicitly %s without exposure qualifier",
7738 uentry_ekindName (unew),
7739 uentry_getName (unew),
7740 uentry_isDeclared (old),
7742 exkind_unparse (newKind),
7743 uentry_specOrDefName (old)),
7744 uentry_whereDeclared (unew)))
7746 uentry_showWhereSpecified (old);
7749 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7755 if (completeConform && exkind_isKnown (oldKind)
7756 && uentry_isReallySpecified (old))
7760 message ("%s %q specified as %s, but declared without "
7761 "exposure qualifier",
7762 ekind_capName (unew->ukind),
7763 uentry_getName (unew),
7764 exkind_unparse (oldKind)),
7765 uentry_whereDeclared (unew)))
7767 uentry_showWhereSpecified (old);
7771 /* yes, this is necessary! (if its a param) */
7772 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7777 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7778 bool mustConform, /*@unused@*/ bool completeConform)
7780 valueTable newvals = sRef_getValueTable (unew->sref);
7782 if (valueTable_isDefined (newvals))
7784 DPRINTF (("Check meta state: %s -> %s",
7785 uentry_unparseFull (old),
7786 uentry_unparseFull (unew)));
7788 DPRINTF (("Check meta state refs: %s -> %s",
7789 sRef_unparseFull (old->sref),
7790 sRef_unparseFull (unew->sref)));
7792 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7795 ** Copy the new values into the old ref
7798 valueTable_elements (newvals, key, newval)
7800 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7801 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7803 llassert (metaStateInfo_isDefined (msinfo));
7805 if (stateValue_isUndefined (oldval))
7807 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7811 if (stateValue_isError (oldval))
7813 if (!stateValue_isError (newval))
7815 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7819 ; /* No change necessary. */
7824 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7826 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7832 if (!stateValue_isError (newval)
7833 && !stateValue_isImplicit (newval))
7835 if (uentry_hasName (unew)
7836 || !sRef_isParam (uentry_getSref (unew)))
7841 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7842 uentry_ekindName (unew),
7843 uentry_getName (unew),
7844 uentry_isDeclared (old),
7846 stateValue_unparseValue (newval, msinfo),
7847 uentry_specOrDefName (old),
7848 stateValue_unparseValue (oldval, msinfo)),
7849 uentry_whereDeclared (unew)))
7851 uentry_showWhereSpecified (old);
7859 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7860 uentry_ekindName (unew),
7861 sRef_getParam (uentry_getSref (unew)),
7862 uentry_isDeclared (old),
7864 stateValue_unparseValue (newval, msinfo),
7865 uentry_specOrDefName (old),
7866 stateValue_unparseValue (oldval, msinfo)),
7867 uentry_whereDeclared (unew)))
7869 uentry_showWhereSpecified (old);
7875 DPRINTF (("Updating!"));
7876 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7880 DPRINTF (("Values match"));
7884 } end_valueTable_elements ;
7889 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7890 /*@notnull@*/ uentry unew,
7891 bool mustConform, bool completeConform)
7893 checkDefState (old, unew, mustConform, completeConform);
7894 checkNullState (old, unew, mustConform, completeConform);
7895 checkAliasState (old, unew, mustConform, completeConform);
7896 checkExpState (old, unew, mustConform, completeConform);
7897 checkMetaState (old, unew, mustConform, completeConform);
7899 sRef_storeState (old->sref);
7900 sRef_storeState (unew->sref);
7904 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7906 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7911 llassert (uentry_isVar (old));
7912 llassert (uentry_isVar (unew));
7914 if (cstring_isEmpty (old->uname))
7916 cstring_free (old->uname);
7917 old->uname = cstring_copy (unew->uname);
7920 if (unew->info->var->kind == VKRETPARAM
7921 || unew->info->var->kind == VKSEFRETPARAM)
7923 if (old->info->var->kind != VKRETPARAM
7924 && old->info->var->kind != VKSEFRETPARAM)
7928 message ("Parameter %q inconsistently %rdeclared as "
7929 "returned parameter",
7930 uentry_getName (unew),
7931 uentry_isDeclared (old)),
7932 uentry_whereDeclared (unew)))
7934 uentry_showWhereSpecified (old);
7935 old->info->var->kind = unew->info->var->kind;
7941 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7943 if (old->info->var->kind != VKSEFPARAM
7944 && old->info->var->kind != VKSEFRETPARAM)
7948 message ("Parameter %qinconsistently %rdeclared as "
7950 uentry_getOptName (unew),
7951 uentry_isDeclared (old)),
7952 uentry_whereDeclared (unew)))
7954 uentry_showWhereSpecified (old);
7955 old->info->var->kind = unew->info->var->kind;
7960 if (old->info->var->kind == VKSPEC)
7962 old->info->var->kind = unew->info->var->kind;
7966 unew->info->var->kind = old->info->var->kind;
7969 if (unew->info->var->checked != CH_UNKNOWN
7970 && unew->info->var->checked != old->info->var->checked)
7972 if (old->info->var->checked == CH_UNKNOWN
7973 && !fileloc_isUser (uentry_whereLast (old)))
7981 message ("Variable %q inconsistently %rdeclared as "
7982 "%s parameter (was %s)",
7983 uentry_getName (unew),
7984 uentry_isDeclared (old),
7985 checkedName (unew->info->var->checked),
7986 checkedName (old->info->var->checked)),
7987 uentry_whereDeclared (unew)))
7989 uentry_showWhereSpecified (old);
7993 old->info->var->checked = unew->info->var->checked;
7998 && (old->info->var->checked != CH_UNKNOWN)
7999 && uentry_isReallySpecified (old))
8003 message ("%s %q specified as %s, but declared without %s qualifier",
8004 ekind_capName (unew->ukind),
8005 uentry_getName (unew),
8006 checkedName (old->info->var->checked),
8007 checkedName (old->info->var->checked)),
8008 uentry_whereDeclared (unew)))
8010 uentry_showWhereSpecified (old);
8014 unew->info->var->checked = old->info->var->checked;
8017 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8020 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8022 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8027 llassert (uentry_isVar (u1));
8028 llassert (uentry_isVar (u2));
8030 if (u1->info->var->kind != u2->info->var->kind) {
8031 if (u1->info->var->kind == VKSEFRETPARAM) {
8032 if (u2->info->var->kind == VKRETPARAM) {
8035 message ("Function types are inconsistent. Parameter %d is "
8036 "sef parameter, but non-sef parameter in "
8037 "assigned function: %s",
8038 paramno, exprNode_unparse (e)),
8040 } else if (u2->info->var->kind == VKSEFPARAM) {
8043 message ("Function types are inconsistent. Parameter %d is "
8044 "returns parameter, but non-returns parameter in "
8045 "assigned function: %s",
8046 paramno, exprNode_unparse (e)),
8051 message ("Function types are inconsistent. Parameter %d is "
8052 "sef returns parameter, but non-sef returns parameter in "
8053 "assigned function: %s",
8054 paramno, exprNode_unparse (e)),
8057 } else if (u1->info->var->kind == VKRETPARAM) {
8060 message ("Function types are inconsistent. Parameter %d is "
8061 "returns parameter, but non-returns parameter in "
8062 "assigned function: %s",
8063 paramno, exprNode_unparse (e)),
8065 } else if (u1->info->var->kind == VKSEFPARAM) {
8068 message ("Function types are inconsistent. Parameter %d is "
8069 "sef parameter, but non-sef parameter in "
8070 "assigned function: %s",
8071 paramno, exprNode_unparse (e)),
8074 if (u2->info->var->kind == VKSEFRETPARAM) {
8077 message ("Function types are inconsistent. Parameter %d is "
8078 "normal parameter, but sef returns parameter in "
8079 "assigned function: %s",
8080 paramno, exprNode_unparse (e)),
8082 } else if (u2->info->var->kind == VKSEFPARAM) {
8085 message ("Function types are inconsistent. Parameter %d is "
8086 "normal parameter, but sef parameter in "
8087 "assigned function: %s",
8088 paramno, exprNode_unparse (e)),
8090 } else if (u2->info->var->kind == VKRETPARAM) {
8093 message ("Function types are inconsistent. Parameter %d is "
8094 "normal parameter, but returns parameter in "
8095 "assigned function: %s",
8096 paramno, exprNode_unparse (e)),
8104 if (u1->info->var->defstate != u2->info->var->defstate)
8108 message ("Function types are inconsistent. Parameter %d is "
8109 "%s, but %s in assigned function: %s",
8111 sstate_unparse (u1->info->var->defstate),
8112 sstate_unparse (u2->info->var->defstate),
8113 exprNode_unparse (e)),
8117 if (u1->info->var->nullstate != u2->info->var->nullstate)
8121 message ("Function types are inconsistent. Parameter %d is "
8122 "%s, but %s in assigned function: %s",
8124 nstate_unparse (u1->info->var->nullstate),
8125 nstate_unparse (u2->info->var->nullstate),
8126 exprNode_unparse (e)),
8130 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8134 message ("Function types are inconsistent. Parameter %d is "
8135 "%s, but %s in assigned function: %s",
8137 alkind_unparse (sRef_getAliasKind (u1->sref)),
8138 alkind_unparse (sRef_getAliasKind (u2->sref)),
8139 exprNode_unparse (e)),
8143 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8147 message ("Function types are inconsistent. Parameter %d is "
8148 "%s, but %s in assigned function: %s",
8150 exkind_unparse (sRef_getExKind (u1->sref)),
8151 exkind_unparse (sRef_getExKind (u2->sref)),
8152 exprNode_unparse (e)),
8158 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8159 /*@notnull@*/ uentry unew,
8160 bool mustConform, /*@unused@*/ bool completeConform)
8162 uentryList oldParams = uentry_getParams (old);
8163 uentryList newParams = uentry_getParams (unew);
8164 ctype newType = unew->utype;
8165 ctype oldType = old->utype;
8166 ctype oldRetType = ctype_unknown;
8167 ctype newRetType = ctype_unknown;
8169 DPRINTF (("Function conform: %s ==> %s",
8170 uentry_unparseFull (old),
8171 uentry_unparseFull (unew)));
8173 if (uentry_isForward (old))
8175 mustConform = FALSE;
8176 uentry_updateInto (old, unew);
8181 ** check return values
8184 if (ctype_isKnown (oldType))
8186 llassert (ctype_isFunction (oldType));
8188 oldRetType = ctype_getReturnType (oldType);
8191 if (ctype_isKnown (newType))
8193 llassert (ctype_isFunction (newType));
8195 newRetType = ctype_getReturnType (newType);
8198 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8199 && !ctype_matchDef (newRetType, oldRetType))
8201 if (mustConform) returnValueError (old, unew);
8205 if (ctype_isConj (newRetType))
8207 if (ctype_isConj (oldRetType))
8209 if (!ctype_sameAltTypes (newRetType, oldRetType))
8213 message ("Function %q inconsistently %rdeclared to "
8214 "return alternate types %s "
8215 "(types match, but alternates are not identical, "
8216 "so checking may not be correct)",
8217 uentry_getName (unew),
8218 uentry_isDeclared (old),
8219 ctype_unparse (newRetType)),
8220 uentry_whereDeclared (unew)))
8222 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8228 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8233 DPRINTF (("Before state: %s",
8234 uentry_unparseFull (old)));
8235 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8236 DPRINTF (("After state: %s",
8237 uentry_unparseFull (old)));
8239 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8241 if (exitkind_isKnown (unew->info->fcn->exitCode))
8245 message ("Function %q inconsistently %rdeclared using %s",
8246 uentry_getName (unew),
8247 uentry_isDeclared (old),
8248 exitkind_unparse (unew->info->fcn->exitCode)),
8249 uentry_whereDeclared (unew)))
8251 uentry_showWhereSpecified (old);
8256 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8260 if (!qual_isUnknown (unew->info->fcn->nullPred))
8262 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8266 message ("Function %q inconsistently %rdeclared using %s",
8267 uentry_getName (unew),
8268 uentry_isDeclared (old),
8269 qual_unparse (unew->info->fcn->nullPred)),
8270 uentry_whereDeclared (unew)))
8272 uentry_showWhereSpecified (old);
8278 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8281 if (unew->info->fcn->specialCode != SPC_NONE)
8283 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8287 message ("Function %q inconsistently %rdeclared using %s",
8288 uentry_getName (unew),
8289 uentry_isDeclared (old),
8290 specCode_unparse (unew->info->fcn->specialCode)),
8291 uentry_whereDeclared (unew)))
8293 uentry_showWhereSpecified (old);
8299 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8306 if (!uentryList_sameObject (oldParams, newParams)
8307 && (!uentryList_isMissingParams (oldParams)))
8309 if (!uentryList_isMissingParams (newParams))
8312 int nparams = uentryList_size (oldParams);
8313 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8315 if (nparams != uentryList_size (newParams))
8317 nargsError (old, unew);
8320 if (uentryList_size (newParams) < nparams)
8322 nparams = uentryList_size (newParams);
8325 while (paramno < nparams)
8327 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8328 uentry newCurrent = uentryList_getN (newParams, paramno);
8329 ctype oldCurrentType = uentry_getType (oldCurrent);
8330 ctype newCurrentType = uentry_getType (newCurrent);
8332 llassert (uentry_isValid (oldCurrent)
8333 && uentry_isValid (newCurrent));
8335 if (!uentry_isElipsisMarker (oldCurrent)
8336 && !uentry_isElipsisMarker (newCurrent))
8338 checkVarConformance (oldCurrent, newCurrent,
8339 mustConform, completeConform);
8344 if (uentry_hasName (oldCurrent)
8345 && uentry_hasName (newCurrent))
8347 cstring oldname = uentry_getName (oldCurrent);
8348 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8350 cstring nname = uentry_getName (newCurrent);
8353 if (cstring_isDefined (pfx)
8354 && cstring_equalPrefix (oldname, pfx))
8356 oname = cstring_suffix (oldname, cstring_length (pfx));
8361 /*@-branchstate@*/ } /*@=branchstate@*/
8363 if (cstring_isDefined (pfx)
8364 && cstring_equalPrefix (nname, pfx))
8366 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8371 /*@-branchstate@*/ } /*@=branchstate@*/
8373 if (!cstring_equal (oname, nnamefix))
8376 (FLG_DECLPARAMMATCH,
8377 message ("Definition parameter name %s does not match "
8378 "name of corresponding parameter in "
8381 uentry_whereLast (newCurrent)))
8383 uentry_showWhereLastPlain (oldCurrent);
8387 cstring_free (oldname);
8388 cstring_free (nname);
8392 if (!ctype_match (oldCurrentType, newCurrentType))
8394 paramTypeError (old, oldCurrent, oldCurrentType,
8395 unew, newCurrent, newCurrentType, paramno);
8399 if (ctype_isMissingParamsMarker (newCurrentType)
8400 || ctype_isElips (newCurrentType)
8401 || ctype_isMissingParamsMarker (oldCurrentType)
8402 || ctype_isElips (oldCurrentType))
8408 if (ctype_isConj (newCurrentType))
8410 if (ctype_isConj (oldCurrentType))
8412 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8416 message ("Parameter %q inconsistently %rdeclared with "
8417 "alternate types %s "
8418 "(types match, but alternates are not identical, "
8419 "so checking may not be correct)",
8420 uentry_getName (newCurrent),
8421 uentry_isDeclared (oldCurrent),
8422 ctype_unparse (newCurrentType)),
8423 uentry_whereDeclared (unew)))
8425 uentry_showWhereLastVal (oldCurrent,
8426 ctype_unparse (oldCurrentType));
8434 message ("Parameter %q inconsistently %rdeclared with "
8435 "alternate types %s",
8436 uentry_getName (newCurrent),
8437 uentry_isDeclared (oldCurrent),
8438 ctype_unparse (newCurrentType)),
8439 uentry_whereDeclared (unew)))
8441 uentry_showWhereLastVal (oldCurrent,
8442 ctype_unparse (oldCurrentType));
8449 if (ctype_isConj (oldCurrentType))
8451 uentry_setType (newCurrent, oldCurrentType);
8459 ** Forgot this! detected by lclint:
8460 ** uentry.c:1257,15: Suspected infinite loop
8466 if (!uentryList_isMissingParams (newParams))
8468 if (ctype_isConj (oldRetType))
8470 old->utype = ctype_makeFunction (oldRetType,
8471 uentryList_copy (newParams));
8475 old->utype = unew->utype;
8479 checkGlobalsConformance (old, unew, mustConform, completeConform);
8480 checkModifiesConformance (old, unew, mustConform, completeConform);
8482 DPRINTF (("Before list: %s",
8483 uentry_unparseFull (old)));
8485 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8487 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8492 message ("Function %q redeclared using special clauses (can only "
8493 "be used in first declaration)",
8494 uentry_getName (unew)),
8495 uentry_whereDeclared (unew)))
8497 uentry_showWhereLast (old);
8501 /*@i23 need checking @*/
8503 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8507 /*@i43 should be able to append? @*/
8509 stateClauseList_checkEqual (old, unew);
8510 stateClauseList_free (unew->info->fcn->specclauses);
8511 unew->info->fcn->specclauses = stateClauseList_undefined;
8514 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8517 if (fileloc_isUndefined (old->whereDeclared))
8519 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8521 else if (fileloc_isUndefined (unew->whereDeclared))
8523 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8532 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8536 llassert (uentry_isValid (ue));
8537 llassert (uentry_isEitherConstant (ue));
8539 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8540 uval = uentry_getConstantValue (ue);
8542 if (multiVal_isDefined (uval))
8544 if (multiVal_isDefined (m))
8546 if (!multiVal_equiv (uval, m))
8550 message ("%s %q defined with inconsistent value: %q",
8551 ekind_capName (ue->ukind),
8552 uentry_getName (ue),
8553 multiVal_unparse (m)),
8556 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8564 uentry_setConstantValue (ue, m);
8569 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8572 bool typeError = FALSE;
8574 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8576 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8580 DPRINTF (("Check struct conformance: %s / %s",
8581 uentry_unparseFull (old),
8582 uentry_unparseFull (unew)));
8583 checkStructConformance (old, unew);
8588 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8590 llbug (message ("struct tags: bad types: %t / %t",
8591 old->utype, unew->utype));
8595 else if (uentry_isEnumTag (old))
8597 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8599 if (mustConform) checkEnumConformance (old, unew);
8603 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8605 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8606 ctype_unparse (unew->utype)));
8610 else if (!ctype_match (old->utype, unew->utype))
8612 DPRINTF (("Type mismatch: %s / %s",
8613 ctype_unparse (old->utype),
8614 ctype_unparse (unew->utype)));
8616 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8618 ctype realt = ctype_realType (unew->utype);
8620 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8622 unew->utype = ctype_bool;
8628 typeError = optgenerror
8630 message ("%q defined as %s", uentry_getName (old),
8631 ctype_unparse (realt)),
8632 uentry_whereDeclared (unew));
8640 ctype oldr = ctype_realType (old->utype);
8641 ctype newr = ctype_realType (unew->utype);
8643 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8645 checkStructConformance (old, unew);
8647 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8649 checkStructConformance (old, unew);
8651 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8653 checkEnumConformance (old, unew);
8655 else if (uentry_isConstant (old)
8656 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8658 /* okay...for now! (should check the type is reset later... */
8662 DPRINTF (("YABA!"));
8665 message ("%s %q %rdeclared with inconsistent type: %t",
8666 ekind_capName (unew->ukind),
8667 uentry_getName (unew),
8668 uentry_isDeclared (old),
8670 uentry_whereDeclared (unew)))
8672 uentry_showWhereLast (old);
8688 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8689 /*@notnull@*/ uentry unew,
8690 bool mustConform, bool completeConform)
8692 if (ctype_isDefined (unew->info->datatype->type))
8695 ** bool is hard coded here, since it is built into LCL.
8696 ** For now, we're stuck with LCL's types.
8699 if (ctype_isDirectBool (old->utype) &&
8700 cstring_equalLit (unew->uname, "bool"))
8702 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8703 evs 2000-07-25: removed
8705 unew->utype = ctype_bool;
8708 if (ctype_isUnknown (old->info->datatype->type))
8710 old->info->datatype->type = unew->info->datatype->type;
8714 DPRINTF (("Old: %s / New: %s",
8715 uentry_unparseFull (old),
8716 uentry_unparseFull (unew)));
8717 DPRINTF (("Types: %s / %s",
8718 ctype_unparse (old->info->datatype->type),
8719 ctype_unparse (unew->info->datatype->type)));
8721 if (ctype_matchDef (old->info->datatype->type,
8722 unew->info->datatype->type))
8731 ("Type %q %s with inconsistent type: %t",
8732 uentry_getName (unew),
8733 uentry_reDefDecl (old, unew),
8734 unew->info->datatype->type),
8735 uentry_whereDeclared (unew)))
8737 uentry_showWhereLastExtra
8738 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8741 old->info->datatype->type = unew->info->datatype->type;
8746 if (unew->info->datatype->abs != MAYBE)
8748 if (ynm_isOff (old->info->datatype->abs)
8749 && ynm_isOn (unew->info->datatype->abs))
8751 if (!ctype_isDirectBool (old->utype))
8756 ("Datatype %q inconsistently %rdeclared as abstract type",
8757 uentry_getName (unew),
8758 uentry_isDeclared (old)),
8759 uentry_whereDeclared (unew)))
8761 uentry_showWhereLastPlain (old);
8765 else if (ynm_isOn (old->info->datatype->abs)
8766 && ynm_isOff (unew->info->datatype->abs))
8768 if (!ctype_isDirectBool (old->utype))
8773 ("Datatype %q inconsistently %rdeclared as concrete type",
8774 uentry_getName (unew),
8775 uentry_isDeclared (old)),
8776 uentry_whereDeclared (unew)))
8778 uentry_showWhereLastPlain (old);
8789 if (ynm_isOn (old->info->datatype->abs))
8791 old->sref = unew->sref;
8792 unew->info->datatype->mut = old->info->datatype->mut;
8795 && uentry_isReallySpecified (old))
8800 ("Datatype %q specified as abstract, "
8801 "but abstract annotation not used in declaration",
8802 uentry_getName (unew)),
8803 uentry_whereDeclared (unew)))
8805 uentry_showWhereLastPlain (old);
8811 unew->info->datatype->abs = old->info->datatype->abs;
8813 if (ynm_isMaybe (unew->info->datatype->mut))
8815 if (completeConform && ynm_isOff (old->info->datatype->mut)
8816 && uentry_isReallySpecified (old))
8821 ("Datatype %q specified as immutable, "
8822 "but immutable annotation not used in declaration",
8823 uentry_getName (unew)),
8824 uentry_whereDeclared (unew)))
8826 uentry_showWhereLastPlain (old);
8830 unew->info->datatype->mut = old->info->datatype->mut;
8832 else if (ynm_isMaybe (old->info->datatype->mut))
8834 old->info->datatype->mut = unew->info->datatype->mut;
8838 if (ynm_isOn (old->info->datatype->abs))
8840 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8844 message ("Datatype %q inconsistently %rdeclared as immutable",
8845 uentry_getName (unew),
8846 uentry_isDeclared (old)),
8847 uentry_whereDeclared (unew)))
8849 uentry_showWhereLastPlain (old);
8854 if (ynm_isOff (old->info->datatype->mut)
8855 && ynm_isOn (unew->info->datatype->mut))
8859 message ("Datatype %q inconsistently %rdeclared as mutable",
8860 uentry_getName (unew),
8861 uentry_isDeclared (old)),
8862 uentry_whereDeclared (unew)))
8864 uentry_showWhereLastPlain (old);
8869 old->info->datatype->mut = unew->info->datatype->mut;
8872 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8876 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8877 /*@notnull@*/ uentry unew,
8879 /*@unused@*/ bool completeConform)
8881 multiVal oldval = uentry_getConstantValue (old);
8882 multiVal newval = uentry_getConstantValue (unew);
8884 if (multiVal_isDefined (oldval))
8886 if (multiVal_isDefined (newval))
8888 if (!multiVal_equiv (oldval, newval))
8893 message ("%s %q %rdeclared with inconsistent value: %q",
8894 ekind_capName (unew->ukind),
8895 uentry_getName (unew),
8896 uentry_isDeclared (old),
8897 multiVal_unparse (newval)),
8898 uentry_whereDeclared (unew)))
8900 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8904 uentry_setConstantValue (unew, multiVal_copy (oldval));
8913 uentry_setConstantValue (old, multiVal_copy (newval));
8918 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8919 /*@notnull@*/ uentry unew, bool mustConform,
8920 bool completeConform)
8922 bool typeError = FALSE;
8923 bool fcnConformance = FALSE;
8925 if (!ekind_equal (unew->ukind, old->ukind))
8928 ** okay, only if one is a function and the other is
8929 ** a variable of type function.
8932 if (unew->ukind == KENUMCONST
8933 && old->ukind == KCONST)
8935 old->ukind = KENUMCONST;
8939 if (unew->ukind == KFCN
8940 && old->ukind == KCONST
8941 && ctype_isUnknown (old->utype))
8944 ** When a function is defined with an unparam macro
8947 uentry_updateInto (old, unew);
8951 if (uentry_isExpandedMacro (old)
8952 && uentry_isEitherConstant (unew))
8954 uentry_updateInto (old, unew);
8958 if (uentry_isEndIter (unew))
8960 if (ctype_isUnknown (old->utype))
8962 if (!uentry_isSpecified (old)
8963 && uentry_isCodeDefined (unew))
8965 if (!fileloc_withinLines (uentry_whereDefined (old),
8966 uentry_whereDeclared (unew), 2))
8967 { /* bogus! will give errors if there is too much whitespace */
8971 ("Iterator finalized name %q does not match name in "
8972 "previous iter declaration (should be end_%q). This iter "
8973 "is declared at %q",
8974 uentry_getName (unew),
8975 uentry_getName (old),
8976 fileloc_unparse (uentry_whereDefined (old))),
8977 uentry_whereDeclared (old));
8981 uentry_updateInto (old, unew);
8986 KindConformanceError (old, unew, mustConform);
8990 if (uentry_isFunction (unew))
8992 if (uentry_isVariable (old))
8994 if (!ctype_isUnknown (old->utype))
8996 if (ctype_isFunction (old->utype))
8998 uentry_makeVarFunction (old);
8999 checkFunctionConformance (old, unew, mustConform,
9001 fcnConformance = TRUE;
9005 KindConformanceError (old, unew, mustConform);
9010 if (uentry_isExpandedMacro (old))
9012 if (fileloc_isUndefined (unew->whereDefined))
9014 unew->whereDefined = fileloc_update (unew->whereDefined,
9018 uentry_updateInto (old, unew);
9019 old->used = unew->used = TRUE;
9024 /* undeclared identifier */
9025 old->utype = unew->utype;
9026 uentry_makeVarFunction (old);
9027 checkFunctionConformance (old, unew, FALSE, FALSE);
9028 fcnConformance = TRUE;
9034 KindConformanceError (old, unew, mustConform);
9037 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9039 if (!ctype_isUnknown (unew->utype))
9041 if (ctype_isFunction (unew->utype))
9043 uentry_makeVarFunction (unew);
9044 checkFunctionConformance (old, unew, mustConform, completeConform);
9045 fcnConformance = TRUE;
9049 KindConformanceError (old, unew, mustConform);
9054 KindConformanceError (old, unew, mustConform);
9059 KindConformanceError (old, unew, mustConform);
9065 ** check parameter lists for functions
9066 ** (before type errors, to get better messages
9069 if (uentry_isFunction (old))
9071 checkFunctionConformance (old, unew, mustConform, completeConform);
9072 fcnConformance = TRUE;
9076 if (!ctype_isUndefined (old->utype))
9078 typeError = checkTypeConformance (old, unew, mustConform);
9085 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9087 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9090 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9092 DPRINTF (("Check datatype: %s / %s",
9093 uentry_unparseFull (old),
9094 uentry_unparseFull (unew)));
9096 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9099 if (uentry_isVariable (old) && uentry_isVariable (unew))
9102 !ctype_matchDef (old->utype, unew->utype))
9107 ("Variable %q %s with inconsistent type (arrays and pointers are "
9108 "not identical in variable declarations): %t",
9109 uentry_getName (unew),
9110 uentry_reDefDecl (old, unew),
9112 uentry_whereDeclared (unew)))
9114 uentry_showWhereLast (old);
9117 ** Avoid repeated errors.
9120 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9122 old->whereDefined = fileloc_update (old->whereDefined,
9130 checkVarConformance (old, unew, mustConform, completeConform);
9135 /* old->utype = unew->utype; */
9139 if (ctype_isConj (old->utype))
9141 if (ctype_isConj (unew->utype))
9143 if (!ctype_sameAltTypes (old->utype, unew->utype))
9147 message ("%s %q inconsistently %rdeclared with "
9148 "alternate types %s "
9149 "(types match, but alternates are not identical, "
9150 "so checking may not be correct)",
9151 ekind_capName (uentry_getKind (old)),
9152 uentry_getName (unew),
9153 uentry_isDeclared (old),
9154 ctype_unparse (unew->utype)),
9155 uentry_whereDeclared (unew)))
9157 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9161 old->utype = unew->utype;
9168 if (ctype_isUnknown (old->utype))
9170 old->utype = unew->utype;
9175 if (unew->ukind == old->ukind)
9178 unew->info = uinfo_copy (old->info, old->ukind);
9181 sRef_storeState (old->sref);
9182 sRef_storeState (unew->sref);
9185 static void uentry_mergeConstraints (uentry spec, uentry def)
9187 if (uentry_isFunction (def))
9189 DPRINTF (("Here: %s / %s",
9190 uentry_unparseFull (spec),
9191 uentry_unparseFull (def)));
9192 /* evans 2001-07-21 */
9193 llassert (uentry_isFunction (spec));
9195 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9197 if (fileloc_isXHFile (uentry_whereLast (def)))
9199 llassert (uentry_isFunction (spec));
9200 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9201 def->info->fcn->preconditions);
9203 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9209 /* Check if the constraints are identical */
9214 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9215 uentry_getName (spec),
9216 functionConstraint_unparse (spec->info->fcn->preconditions)),
9217 uentry_whereLast (def)))
9219 uentry_showWhereSpecified (spec);
9222 functionConstraint_free (spec->info->fcn->preconditions);
9223 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9226 def->info->fcn->preconditions = functionConstraint_undefined;
9229 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9231 if (fileloc_isXHFile (uentry_whereLast (def)))
9233 llassert (uentry_isFunction (spec));
9234 DPRINTF (("Post: %s /++/ %s",
9235 functionConstraint_unparse (spec->info->fcn->postconditions),
9236 functionConstraint_unparse (def->info->fcn->postconditions)));
9237 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9238 def->info->fcn->postconditions);
9239 def->info->fcn->postconditions = functionConstraint_undefined;
9240 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9247 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9248 uentry_getName (spec),
9249 functionConstraint_unparse (spec->info->fcn->postconditions)),
9250 uentry_whereLast (def)))
9252 uentry_showWhereSpecified (spec);
9255 functionConstraint_free (spec->info->fcn->postconditions);
9256 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9257 def->info->fcn->postconditions = functionConstraint_undefined;
9264 ** modifies spec to reflect def, reports any inconsistencies
9268 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9270 llassert (uentry_isValid (spec));
9271 llassert (uentry_isValid (def));
9272 llassert (cstring_equal (spec->uname, def->uname));
9274 if (uentry_isFunction (def))
9276 if (uentry_isConstant (spec))
9278 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9279 uentry_makeConstantFunction (spec);
9283 uentry_convertVarFunction (spec);
9286 llassert (uentry_isFunction (spec));
9289 DPRINTF (("Merge entries: %s / %s",
9290 uentry_unparseFull (spec),
9291 uentry_unparseFull (def)));
9293 uentry_mergeConstraints (spec, def);
9295 uentry_checkConformance (spec, def, TRUE,
9296 context_getFlag (FLG_NEEDSPEC));
9298 DPRINTF (("Merge entries after conform: %s / %s",
9299 uentry_unparseFull (spec),
9300 uentry_unparseFull (def)));
9302 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9305 ** okay, declarations conform. Propagate extra information.
9308 uentry_setDefined (spec, uentry_whereDefined (def));
9309 uentry_setDeclared (spec, uentry_whereDeclared (def));
9311 if (uentry_isStatic (def))
9315 message ("%s %q specified, but declared as static",
9316 ekind_capName (def->ukind),
9317 uentry_getName (def)),
9318 uentry_whereDeclared (def)))
9320 uentry_showWhereSpecified (spec);
9325 spec->storageclass = def->storageclass;
9328 sRef_storeState (spec->sref);
9330 spec->used = def->used || spec->used;
9331 spec->hasNameError |= def->hasNameError;
9335 if (!spec->hasNameError)
9337 uentry_checkName (spec);
9346 ** Can't generate function redeclaration errors when the
9347 ** entries are merged, since we don't yet know if its the
9348 ** definition of the function.
9352 uentry_clearDecl (void)
9354 posRedeclared = uentry_undefined;
9355 fileloc_free (posLoc);
9356 posLoc = fileloc_undefined;
9360 uentry_checkDecl (void)
9362 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9364 llassert (fileloc_isDefined (posLoc));
9366 if (uentry_isCodeDefined (posRedeclared))
9368 if (optgenerror (FLG_REDECL,
9369 message ("%s %q declared after definition",
9370 ekind_capName (posRedeclared->ukind),
9371 uentry_getName (posRedeclared)),
9374 llgenindentmsg (message ("Definition of %q",
9375 uentry_getName (posRedeclared)),
9376 posRedeclared->whereDeclared);
9381 if (optgenerror (FLG_REDECL,
9382 message ("%s %q declared more than once",
9383 ekind_capName (posRedeclared->ukind),
9384 uentry_getName (posRedeclared)),
9387 llgenindentmsg (message ("Previous declaration of %q",
9388 uentry_getName (posRedeclared)),
9389 posRedeclared->whereDeclared);
9394 fileloc_free (posLoc);
9395 posLoc = fileloc_undefined;
9396 posRedeclared = uentry_undefined;
9400 ** Redefinition of old as unew.
9401 ** modifies old to reflect unew, reports any inconsistencies
9405 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9407 fileloc olddef = uentry_whereDeclared (old);
9408 fileloc unewdef = uentry_whereDeclared (unew);
9412 DPRINTF (("uentry merge: %s / %s",
9413 uentry_unparseFull (old),
9414 uentry_unparseFull (unew)));
9417 fileloc_isUndefined (olddef)
9418 && fileloc_isDefined (uentry_whereDefined (old))
9419 && !uentry_isExpandedMacro (old);
9421 if (!context_getFlag (FLG_INCONDEFSLIB)
9422 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9424 mustConform = FALSE;
9431 llassert (uentry_isValid (old));
9432 llassert (uentry_isValid (unew));
9433 llassert (cstring_equal (old->uname, unew->uname));
9435 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9437 if (uentry_isConstant (old))
9439 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9440 uentry_makeConstantFunction (old);
9444 uentry_convertVarFunction (old);
9447 llassert (uentry_isFunction (old));
9450 DPRINTF (("uentry merge: %s / %s",
9451 uentry_unparseFull (old),
9452 uentry_unparseFull (unew)));
9454 if (uentry_isExtern (unew))
9456 uentry_setUsed (old, unewdef);
9460 ** should check old one was extern!
9463 if (uentry_isStatic (old))
9465 if (!(uentry_isStatic (unew)))
9469 message ("%s %q shadows static declaration",
9470 ekind_capName (unew->ukind),
9471 uentry_getName (unew)),
9474 uentry_showWhereLast (old);
9479 uentry_setDeclDef (old, unewdef);
9482 else if (uentry_isStatic (unew))
9484 uentry_setDeclDef (old, unewdef);
9486 else if (uentry_isExtern (old))
9488 uentry_setDeclared (old, unewdef);
9492 if (!uentry_isExtern (unew)
9493 && !uentry_isForward (old)
9494 && !fileloc_equal (olddef, unewdef)
9495 && !fileloc_isUndefined (olddef)
9496 && !fileloc_isUndefined (unewdef)
9497 && !fileloc_isBuiltin (olddef)
9498 && !fileloc_isBuiltin (unewdef)
9499 && !uentry_isYield (old)
9500 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9502 if (uentry_isVariable (old) || uentry_isVariable (unew))
9504 ; /* will report redeclaration error later */
9508 if (fileloc_isDefined (uentry_whereDefined (old)))
9512 message ("%s %q defined more than once",
9513 ekind_capName (unew->ukind),
9514 uentry_getName (unew)),
9515 uentry_whereLast (unew)))
9518 (message ("Previous definition of %q",
9519 uentry_getName (old)),
9520 uentry_whereLast (old));
9523 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9525 uentry_updateInto (old, unew);
9526 old->sref = sRef_saveCopy (old->sref);
9534 if (fileloc_isLib (olddef)
9535 || fileloc_isUndefined (olddef)
9536 || fileloc_isImport (olddef))
9538 if (uentry_isExtern (unew))
9540 if (uentry_isExtern (old)
9541 || (fileloc_isDefined (uentry_whereDeclared (old))
9542 && (!fileloc_equal (uentry_whereDeclared (old),
9543 uentry_whereDefined (old)))))
9547 message ("%s %q declared more than once",
9548 ekind_capName (unew->ukind),
9549 uentry_getName (unew)),
9550 unew->whereDeclared))
9553 (message ("Previous declaration of %q",
9554 uentry_getName (old)),
9555 old->whereDeclared);
9559 uentry_setExtern (old);
9563 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9569 DPRINTF (("uentry merge: %s / %s",
9570 uentry_unparseFull (old),
9571 uentry_unparseFull (unew)));
9573 uentry_mergeConstraints (old, unew);
9574 DPRINTF (("uentry merge: %s / %s",
9575 uentry_unparseFull (old),
9576 uentry_unparseFull (unew)));
9578 uentry_checkConformance (old, unew, mustConform, FALSE);
9579 DPRINTF (("uentry merge: %s / %s",
9580 uentry_unparseFull (old),
9581 uentry_unparseFull (unew)));
9583 old->used = old->used || unew->used;
9584 old->uses = filelocList_append (old->uses, unew->uses);
9585 unew->uses = filelocList_undefined;
9587 sRef_storeState (old->sref);
9588 sRef_storeState (unew->sref);
9592 old->whereDefined = fileloc_update (old->whereDefined,
9596 DPRINTF (("here: %s", uentry_unparseFull (old)));
9599 ** No redeclaration errors for functions here, since we
9600 ** don't know if this is the definition of the function.
9603 if (fileloc_isUser (old->whereDeclared)
9604 && fileloc_isUser (unew->whereDeclared)
9605 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9606 && !fileloc_isDefined (unew->whereDefined))
9608 if (uentry_isFunction (old))
9610 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9611 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9615 if (optgenerror (FLG_REDECL,
9616 message ("%s %q declared more than once",
9617 ekind_capName (unew->ukind),
9618 uentry_getName (unew)),
9619 unew->whereDeclared))
9621 llgenindentmsg (message ("Previous declaration of %q",
9622 uentry_getName (old)),
9623 old->whereDeclared);
9628 if (fileloc_isUndefined (old->whereDefined))
9630 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9634 if (!context_processingMacros ()
9635 && fileloc_isUser (old->whereDefined)
9636 && fileloc_isUser (unew->whereDefined)
9637 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9639 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9641 if (uentry_isVariable (unew)
9642 && uentry_isExtern (unew))
9644 if (optgenerror (FLG_REDECL,
9645 message ("%s %q declared after definition",
9646 ekind_capName (unew->ukind),
9647 uentry_getName (unew)),
9648 unew->whereDeclared))
9650 llgenindentmsg (message ("Definition of %q",
9651 uentry_getName (old)),
9657 if (optgenerror (FLG_REDEF,
9658 message ("%s %q redefined",
9659 ekind_capName (unew->ukind),
9660 uentry_getName (unew)),
9661 unew->whereDefined))
9663 llgenindentmsg (message ("Previous definition of %q",
9664 uentry_getName (old)),
9672 if (uentry_isExternal (unew))
9674 old->whereDefined = fileloc_createExternal ();
9677 if (unew->hasNameError)
9679 old->hasNameError = TRUE;
9684 if (!old->hasNameError)
9686 uentry_checkName (old);
9689 DPRINTF (("After: %s", uentry_unparseFull (old)));
9690 llassert (!ctype_isUndefined (old->utype));
9694 uentry_copyState (uentry res, uentry other)
9696 llassert (uentry_isValid (res));
9697 llassert (uentry_isValid (other));
9699 res->used = other->used;
9701 res->info->var->kind = other->info->var->kind;
9702 res->info->var->defstate = other->info->var->defstate;
9703 res->info->var->nullstate = other->info->var->nullstate;
9704 res->info->var->checked = other->info->var->checked;
9706 sRef_copyState (res->sref, other->sref);
9710 uentry_sameKind (uentry u1, uentry u2)
9712 if (uentry_isValid (u1) && uentry_isValid (u2))
9714 if (uentry_isVar (u1) && uentry_isVar (u2))
9716 ctype c1 = u1->utype;
9717 ctype c2 = u2->utype;
9719 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9722 ** both functions, or both not functions
9725 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9729 return ((u1->ukind == u2->ukind));
9736 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9738 ekind okind = unew->ukind;
9739 llassert (uentry_isValid (unew));
9740 llassert (uentry_isValid (old));
9742 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9744 unew->ukind = old->ukind;
9745 llassert (cstring_equal (unew->uname, old->uname));
9746 unew->utype = old->utype;
9748 if (fileloc_isDefined (unew->whereSpecified)
9749 && !fileloc_isDefined (old->whereSpecified))
9751 ; /* Keep the old value */
9755 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9756 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9759 if (fileloc_isDefined (unew->whereDefined)
9760 && !fileloc_isDefined (old->whereDefined))
9762 ; /* Keep the old value */
9766 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9767 unew->whereDefined = fileloc_copy (old->whereDefined);
9770 if (fileloc_isDefined (unew->whereDeclared)
9771 && !fileloc_isDefined (old->whereDeclared))
9773 ; /* Keep the old value */
9777 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9778 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9781 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9783 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9784 unew->used = old->used;
9786 unew->isPrivate = old->isPrivate;
9787 unew->hasNameError = old->hasNameError;
9788 unew->uses = filelocList_append (unew->uses, old->uses);
9789 old->uses = filelocList_undefined;
9791 unew->storageclass = old->storageclass;
9792 uinfo_free (unew->info, okind);
9793 unew->info = uinfo_copy (old->info, old->ukind);
9798 uentry_copy (uentry e)
9800 if (uentry_isValid (e))
9802 uentry enew = uentry_alloc ();
9803 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9804 enew->ukind = e->ukind;
9805 enew->uname = cstring_copy (e->uname);
9806 enew->utype = e->utype;
9808 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9809 enew->whereDefined = fileloc_copy (e->whereDefined);
9810 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9812 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9813 enew->used = e->used;
9815 enew->isPrivate = e->isPrivate;
9816 enew->hasNameError = e->hasNameError;
9817 enew->uses = filelocList_undefined;
9819 enew->storageclass = e->storageclass;
9820 enew->info = uinfo_copy (e->info, e->ukind);
9821 enew->warn = warnClause_copy (e->warn);
9823 DPRINTF (("Here we are..."));
9824 DPRINTF (("original: %s", uentry_unparseFull (e)));
9825 DPRINTF (("copy: %s", uentry_unparse (enew)));
9826 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9831 return uentry_undefined;
9836 uentry_setState (uentry res, uentry other)
9838 llassert (uentry_isValid (res));
9839 llassert (uentry_isValid (other));
9841 llassert (res->ukind == other->ukind);
9842 llassert (res->ukind == KVAR);
9844 res->sref = sRef_saveCopy (other->sref);
9845 res->used = other->used;
9846 filelocList_free (res->uses);
9847 res->uses = other->uses;
9848 other->uses = filelocList_undefined;
9849 res->lset = other->lset;
9853 uentry_mergeUses (uentry res, uentry other)
9855 llassert (uentry_isValid (res));
9856 llassert (uentry_isValid (other));
9858 res->used = other->used || res->used;
9859 res->lset = other->lset || res->lset;
9860 res->uses = filelocList_append (res->uses, other->uses);
9861 other->uses = filelocList_undefined;
9866 ** This is a really ugly routine.
9868 ** gack...fix this one day.
9873 ** >> res is the false branch, other is the true branch (or continuation)
9875 ** >> res is the true branch, other is the false branch (or continutation)
9882 ** References not effected by res are propagated from other.
9886 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9887 bool flip, clause cl, fileloc loc)
9891 message ("%s %q is %s %s, but %s %s.",
9892 ekind_capName (res->ukind), uentry_getName (res),
9893 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9894 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9897 if (sRef_isDead (res->sref))
9899 sRef_showStateInfo (res->sref);
9901 else if (sRef_isKept (res->sref))
9903 sRef_showAliasInfo (res->sref);
9905 else /* dependent */
9907 sRef_showAliasInfo (res->sref);
9908 sRef_showAliasInfo (other->sref);
9911 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9915 static bool incompatibleStates (sRef rs, sRef os)
9917 alkind rk = sRef_getAliasKind (rs);
9918 alkind ok = sRef_getAliasKind (os);
9920 if (alkind_isError (rk) || alkind_isError (ok))
9926 return ((sRef_isDead (rs)
9927 || (alkind_isKept (rk) && !alkind_isKept (ok))
9928 || (alkind_isDependent (rk)
9929 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9930 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9935 branchStateAltError (/*@notnull@*/ uentry res,
9936 /*@notnull@*/ uentry other, bool flip,
9937 clause cl, fileloc loc)
9941 message ("%s %q is %s %s, but %s %s.",
9942 ekind_capName (res->ukind), uentry_getName (res),
9943 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
9944 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
9947 if (sRef_isDead (other->sref))
9949 sRef_showStateInfo (other->sref);
9953 sRef_showAliasInfo (other->sref);
9956 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9957 sRef_setDefinedComplete (res->sref, fileloc_undefined);
9959 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
9960 sRef_setDefinedComplete (other->sref, fileloc_undefined);
9965 ** A reference is relevant for certain checks, only if it
9966 ** is not definitely null on this path (but not declared
9967 ** to always be null.)
9970 static bool uentry_relevantReference (sRef sr, bool flip)
9972 if (sRef_isKept (sr) || sRef_isDependent (sr))
9980 return !sRef_definitelyNullContext (sr);
9984 return !sRef_definitelyNullAltContext (sr);
9990 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
9991 bool mustReturn, bool flip, bool opt,
9994 DPRINTF (("Merge alias states: %s / %s",
9995 uentry_unparseFull (res),
9996 uentry_unparseFull (other)));
9998 if (sRef_isValid (res->sref))
10003 if (incompatibleStates (res->sref, other->sref))
10007 if (sRef_isThroughArrayFetch (res->sref)
10008 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10010 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
10012 sRef_maybeKill (res->sref, loc);
10014 else if (sRef_isPossiblyDead (other->sref))
10016 sRef_maybeKill (res->sref, loc);
10025 if (uentry_relevantReference (other->sref, flip))
10028 if (sRef_isLocalParamVar (res->sref)
10029 && (sRef_isLocalState (other->sref)
10030 || sRef_isDependent (other->sref)))
10032 if (sRef_isDependent (res->sref))
10034 sRef_setDependent (other->sref, loc);
10038 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
10043 branchStateError (res, other, flip, cl, loc);
10048 if (sRef_isKept (res->sref))
10050 sRef_setKept (other->sref, loc);
10055 if (incompatibleStates (other->sref, res->sref))
10057 if (uentry_relevantReference (res->sref, !flip))
10059 if (sRef_isLocalParamVar (res->sref)
10060 && (sRef_isDependent (res->sref)
10061 || sRef_isLocalState (res->sref)))
10063 if (sRef_isDependent (other->sref))
10065 sRef_setDependent (res->sref, loc);
10069 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
10074 if (sRef_isParam (other->sref))
10077 ** If the local variable associated
10078 ** with the param has the correct state,
10080 ** (e.g., free (s); s = new(); ...
10083 uentry uvar = usymtab_lookupSafe (other->uname);
10085 if (uentry_isValid (uvar)
10086 && ((sRef_isDead (other->sref)
10087 && sRef_isOnly (uvar->sref))
10088 || (sRef_isDependent (other->sref)
10089 && sRef_isOwned (uvar->sref))))
10095 branchStateAltError (res, other,
10101 DPRINTF (("Here: %s / %s",
10102 uentry_unparseFull (res),
10103 uentry_unparseFull (other)));
10105 branchStateAltError (res, other,
10112 if (sRef_isKept (other->sref))
10114 sRef_setKept (res->sref, loc);
10120 DPRINTF (("Merge opt..."));
10121 sRef_mergeOptState (res->sref, other->sref, cl, loc);
10122 DPRINTF (("Done!"));
10126 sRef_mergeState (res->sref, other->sref, cl, loc);
10131 if (sRef_isModified (other->sref))
10133 sRef_setModified (res->sref);
10140 uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10142 valueTable rvalues;
10143 valueTable ovalues;
10145 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10153 rvalues = sRef_getValueTable (res->sref);
10154 ovalues = sRef_getValueTable (other->sref);
10156 if (valueTable_isUndefined (ovalues))
10158 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10161 else if (valueTable_isUndefined (rvalues))
10164 ** Copy values from other
10168 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10169 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10174 valueTable_elements (ovalues, fkey, fval) {
10176 metaStateInfo minfo;
10177 stateCombinationTable sctable;
10181 tval = valueTable_lookup (rvalues, fkey);
10183 DPRINTF (("Merge value: %s / %s X %s", fkey,
10184 stateValue_unparse (fval), stateValue_unparse (tval)));
10186 minfo = context_lookupMetaStateInfo (fkey);
10187 llassert (stateValue_isDefined (tval));
10189 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10191 DPRINTF (("Cannot find meta state for: %s", fkey));
10196 llassert (metaStateInfo_isDefined (minfo));
10198 if (stateValue_isError (fval)
10199 || sRef_definitelyNullContext (res->sref))
10201 sRef_setMetaStateValueComplete (res->sref,
10202 fkey, stateValue_getValue (fval),
10203 stateValue_getLoc (fval));
10204 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10206 else if (stateValue_isError (tval)
10207 || sRef_definitelyNullAltContext (other->sref))
10209 DPRINTF (("Other branch is definitely null!"));
10211 else if (sRef_isStateUndefined (res->sref)
10212 || sRef_isDead (res->sref))
10214 ; /* Combination state doesn't matter if it is undefined or dead */
10218 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10219 metaStateInfo_unparse (minfo),
10220 stateValue_unparse (fval),
10221 stateValue_unparse (tval)));
10223 DPRINTF (("state values: %d / %d",
10224 stateValue_getValue (fval), stateValue_getValue (tval)));
10226 sctable = metaStateInfo_getMergeTable (minfo);
10228 DPRINTF (("Merge table: %s",
10229 stateCombinationTable_unparse (sctable)));
10231 msg = cstring_undefined;
10233 nval = stateCombinationTable_lookup (sctable,
10234 stateValue_getValue (fval),
10235 stateValue_getValue (tval),
10238 DPRINTF (("nval: %d / %d / %d", nval,
10239 stateValue_getValue (fval), stateValue_getValue (tval)));
10241 if (nval == stateValue_error)
10243 /*@i32 print extra info for assignments@*/
10245 if (uentry_isGlobalMarker (res))
10250 ("Control branches merge with incompatible global states (%s and %s)%q",
10251 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10252 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10253 cstring_isDefined (msg)
10254 ? message (": %s", msg) : cstring_undefined),
10257 sRef_showMetaStateInfo (res->sref, fkey);
10258 sRef_showMetaStateInfo (other->sref, fkey);
10266 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10267 uentry_getName (res),
10268 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10269 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10270 cstring_isDefined (msg)
10271 ? message (": %s", msg) : cstring_undefined),
10274 sRef_showMetaStateInfo (res->sref, fkey);
10275 sRef_showMetaStateInfo (other->sref, fkey);
10276 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10277 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10278 DPRINTF (("Null: %s / %s",
10279 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10280 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10286 if (nval == stateValue_getValue (fval)
10287 && nval != stateValue_getValue (tval))
10289 loc = stateValue_getLoc (fval);
10291 else if (nval == stateValue_getValue (tval)
10292 && nval != stateValue_getValue (fval))
10294 loc = stateValue_getLoc (tval);
10301 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10302 && nval == stateValue_getValue (fval)
10303 && nval == stateValue_getValue (tval))
10309 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10313 } end_valueTable_elements ;
10319 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10320 bool flip, clause cl)
10322 if (cl == DOWHILECLAUSE)
10324 res->used = other->used || res->used;
10325 res->lset = other->lset || res->lset;
10326 res->uses = filelocList_append (res->uses, other->uses);
10327 other->uses = filelocList_undefined;
10331 if (sRef_isMacroParamRef (res->sref)
10332 && !uentry_isSefParam (other)
10333 && !uentry_isSefParam (res))
10335 bool hasError = FALSE;
10337 if (bool_equal (res->used, other->used))
10339 res->used = other->used;
10343 if (other->used && !flip)
10348 message ("Macro parameter %q used in true clause, "
10349 "but not in false clause",
10350 uentry_getName (res)),
10351 uentry_whereDeclared (res));
10358 message ("Macro parameter %q used in false clause, "
10359 "but not in true clause",
10360 uentry_getName (res)),
10361 uentry_whereDeclared (res));
10367 /* make it sef now, prevent more errors */
10368 res->info->var->kind = VKREFSEFPARAM;
10374 res->used = other->used || res->used;
10375 res->lset = other->lset || res->lset;
10376 res->uses = filelocList_append (res->uses, other->uses);
10377 other->uses = filelocList_undefined;
10383 uentry_mergeState (uentry res, uentry other, fileloc loc,
10384 bool mustReturn, bool flip, bool opt,
10387 llassert (uentry_isValid (res));
10388 llassert (uentry_isValid (other));
10390 llassert (res->ukind == other->ukind);
10391 llassert (res->ukind == KVAR);
10393 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10394 uentry_unparseFull (other)));
10396 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10397 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10398 uentry_mergeSetStates (res, other, loc, flip, cl);
10401 void uentry_setUsed (uentry e, fileloc loc)
10403 static bool firstTime = TRUE;
10404 static bool showUses = FALSE;
10405 static bool exportLocal = FALSE;
10407 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10411 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10413 showUses = context_getFlag (FLG_SHOWUSES);
10414 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10419 if (uentry_isValid (e))
10423 if (warnClause_isDefined (e->warn))
10425 flagSpec flg = warnClause_getFlag (e->warn);
10428 if (warnClause_hasMessage (e->warn))
10430 msg = cstring_copy (warnClause_getMessage (e->warn));
10434 msg = message ("Use of possibly dangerous %s",
10435 uentry_ekindNameLC (e));
10439 message ("%q: %q", msg, uentry_getName (e)),
10443 if (sRef_isMacroParamRef (e->sref))
10445 if (uentry_isYield (e) || uentry_isSefParam (e))
10451 if (context_inConditional ())
10455 message ("Macro parameter %q used in conditionally "
10456 "executed code (may or may not be "
10457 "evaluated exactly once)",
10458 uentry_getName (e)),
10461 e->info->var->kind = VKREFSEFPARAM;
10470 message ("Macro parameter %q used more than once",
10471 uentry_getName (e)),
10472 uentry_whereDeclared (e)))
10474 e->info->var->kind = VKREFSEFPARAM;
10481 if ((dp = uentry_directParamNo (e)) >= 0)
10483 uentry_setUsed (usymtab_getParam (dp), loc);
10488 if (!sRef_isLocalVar (e->sref))
10492 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10498 if (context_inMacro ())
10500 e->uses = filelocList_addUndefined (e->uses);
10504 e->uses = filelocList_addDifferentFile
10506 uentry_whereDeclared (e),
10515 bool uentry_isReturned (uentry u)
10517 return (uentry_isValid (u) && uentry_isVar (u)
10518 && (u->info->var->kind == VKRETPARAM
10519 || u->info->var->kind == VKSEFRETPARAM));
10522 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10524 llassert (uentry_isRealFunction (u));
10526 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10528 stateClauseList clauses = uentry_getStateClauseList (u);
10529 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10531 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10532 sRef_setAllocated (res, g_currentloc);
10534 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10535 stateClauseList_unparse (clauses)));
10538 ** This should be in exprNode_reflectEnsuresClause
10541 stateClauseList_postElements (clauses, cl)
10543 if (!stateClause_isGlobal (cl))
10545 sRefSet refs = stateClause_getRefs (cl);
10546 sRefMod modf = stateClause_getEffectFunction (cl);
10548 sRefSet_elements (refs, el)
10550 sRef base = sRef_getRootBase (el);
10552 if (sRef_isResult (base))
10556 sRef sr = sRef_fixBase (el, res);
10557 modf (sr, g_currentloc);
10564 } end_sRefSet_elements ;
10566 } end_stateClauseList_postElements ;
10574 sRefSet prefs = sRefSet_new ();
10575 sRef res = sRef_undefined;
10578 params = uentry_getParams (u);
10580 uentryList_elements (params, current)
10582 if (uentry_isReturned (current))
10584 if (exprNodeList_size (args) >= paramno)
10586 exprNode ecur = exprNodeList_nth (args, paramno);
10587 sRef tref = exprNode_getSref (ecur);
10589 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10591 if (sRef_isValid (tref))
10593 sRef tcref = sRef_copy (tref);
10595 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10597 if (sRef_isDead (tcref))
10599 sRef_setDefined (tcref, g_currentloc);
10600 sRef_setOnly (tcref, g_currentloc);
10603 if (sRef_isRefCounted (tcref))
10605 /* could be a new ref now (but only if its returned) */
10606 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10609 sRef_makeSafe (tcref);
10610 prefs = sRefSet_insert (prefs, tcref);
10616 } end_uentryList_elements ;
10618 if (sRefSet_size (prefs) > 0)
10620 nstate n = sRef_getNullState (u->sref);
10622 if (sRefSet_size (prefs) == 1)
10624 res = sRefSet_choose (prefs);
10628 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10629 res = sRefSet_mergeIntoOne (prefs);
10632 if (nstate_isKnown (n))
10634 sRef_setNullState (res, n, g_currentloc);
10639 if (ctype_isFunction (u->utype))
10641 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10642 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10646 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10649 if (sRef_isRefCounted (res))
10651 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10656 if (sRef_getNullState (res) == NS_ABSNULL)
10658 ctype ct = ctype_realType (u->utype);
10660 if (ctype_isAbstract (ct))
10662 sRef_setNotNull (res, g_currentloc);
10666 if (ctype_isUser (ct))
10668 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10672 sRef_setNotNull (res, g_currentloc);
10677 if (sRef_isRefCounted (res))
10679 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10681 else if (sRef_isKillRef (res))
10683 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10690 ak = sRef_getAliasKind (res);
10692 if (alkind_isImplicit (ak))
10694 sRef_setAliasKind (res,
10695 alkind_fixImplicit (ak),
10699 sRefSet_free (prefs);
10701 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10706 static bool uentry_isRefCounted (uentry ue)
10708 ctype ct = uentry_getType (ue);
10710 if (ctype_isFunction (ct))
10712 return (ctype_isRefCounted (ctype_getReturnType (ct)));
10716 return (ctype_isRefCounted (ct));
10721 ** old was declared yield in the specification.
10722 ** new is declared in the iter implementation.
10725 void uentry_checkYieldParam (uentry old, uentry unew)
10729 llassert (uentry_isVariable (old));
10730 llassert (uentry_isVariable (unew));
10732 unew->info->var->kind = VKYIELDPARAM;
10733 (void) checkTypeConformance (old, unew, TRUE);
10734 checkVarConformance (old, unew, TRUE, FALSE);
10736 /* get rid of param marker */
10738 name = uentry_getName (unew);
10739 cstring_free (unew->uname);
10740 unew->uname = name;
10741 unew->info->var->kind = VKREFYIELDPARAM;
10743 uentry_setUsed (old, fileloc_undefined);
10744 uentry_setUsed (unew, fileloc_undefined);
10747 /*@observer@*/ cstring
10748 uentry_ekindName (uentry ue)
10750 if (uentry_isValid (ue))
10755 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10757 return cstring_makeLiteralTemp ("Datatype");
10759 return cstring_makeLiteralTemp ("Enum member");
10761 return cstring_makeLiteralTemp ("Constant");
10763 if (uentry_isParam (ue))
10765 return cstring_makeLiteralTemp ("Parameter");
10767 else if (uentry_isExpandedMacro (ue))
10769 return cstring_makeLiteralTemp ("Expanded macro");
10773 return cstring_makeLiteralTemp ("Variable");
10776 return cstring_makeLiteralTemp ("Function");
10778 return cstring_makeLiteralTemp ("Iterator");
10780 return cstring_makeLiteralTemp ("Iterator finalizer");
10782 return cstring_makeLiteralTemp ("Struct tag");
10784 return cstring_makeLiteralTemp ("Union tag");
10786 return cstring_makeLiteralTemp ("Enum tag");
10788 return cstring_makeLiteralTemp ("Optional parameters");
10793 return cstring_makeLiteralTemp ("<Undefined>");
10799 /*@observer@*/ cstring
10800 uentry_ekindNameLC (uentry ue)
10802 if (uentry_isValid (ue))
10807 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10809 return cstring_makeLiteralTemp ("datatype");
10811 return cstring_makeLiteralTemp ("enum member");
10813 return cstring_makeLiteralTemp ("constant");
10815 if (uentry_isParam (ue))
10817 return cstring_makeLiteralTemp ("parameter");
10819 else if (uentry_isExpandedMacro (ue))
10821 return cstring_makeLiteralTemp ("expanded macro");
10825 return cstring_makeLiteralTemp ("variable");
10828 return cstring_makeLiteralTemp ("function");
10830 return cstring_makeLiteralTemp ("iterator");
10832 return cstring_makeLiteralTemp ("iterator finalizer");
10834 return cstring_makeLiteralTemp ("struct tag");
10836 return cstring_makeLiteralTemp ("union tag");
10838 return cstring_makeLiteralTemp ("enum tag");
10840 return cstring_makeLiteralTemp ("optional parameters");
10845 return cstring_makeLiteralTemp ("<Undefined>");
10851 void uentry_setHasNameError (uentry ue)
10853 llassert (uentry_isValid (ue));
10855 ue->hasNameError = TRUE;
10858 void uentry_checkName (uentry ue)
10860 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10861 uentry_observeRealName (ue),
10862 bool_unparse (uentry_isVisibleExternally (ue))));
10864 if (uentry_isValid (ue)
10865 && !context_inXHFile ()
10866 && uentry_hasName (ue)
10867 && !uentry_isElipsisMarker (ue)
10868 && context_getFlag (FLG_NAMECHECKS)
10869 && !ue->hasNameError
10870 && !uentry_isEndIter (ue)
10871 && !fileloc_isBuiltin (uentry_whereLast (ue))
10872 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10874 DPRINTF (("Here..."));
10876 if (uentry_isPriv (ue))
10878 ; /* any checks here? */
10880 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10882 ; /* no errors for externals */
10888 if (uentry_isExpandedMacro (ue))
10894 if (uentry_isExpandedMacro (ue))
10898 else if (uentry_isVariable (ue))
10900 sRef sr = uentry_getSref (ue);
10902 if (sRef_isValid (sr))
10904 scope = sRef_getScope (sr);
10911 else if (uentry_isFunction (ue)
10912 || uentry_isIter (ue)
10913 || uentry_isEndIter (ue)
10914 || uentry_isConstant (ue))
10916 scope = uentry_isStatic (ue) ? fileScope : globScope;
10918 else /* datatypes, etc. must be global */
10923 usymtab_checkDistinctName (ue, scope);
10926 if (context_getFlag (FLG_CPPNAMES))
10931 if (scope == globScope)
10933 checkExternalName (ue);
10935 else if (scope == fileScope)
10937 checkFileScopeName (ue);
10941 checkLocalName (ue);
10945 checkAnsiName (ue);
10950 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
10956 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
10959 if (!context_inMacro ())
10961 sRef_setGlobalScopeSafe ();
10964 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
10965 uentry_setUsed (ue, loc);
10967 tloc = fileloc_createExternal ();
10968 uentry_setDefined (ue, tloc);
10969 fileloc_free (tloc);
10970 uentry_setHasNameError (ue);
10972 if (context_getFlag (FLG_REPEATUNRECOG))
10974 uentry_markOwned (ue);
10978 ue = usymtab_supReturnFileEntry (ue);
10981 if (!context_inMacro ())
10983 sRef_clearGlobalScopeSafe ();
10989 uentry uentry_makeGlobalMarker ()
10994 llassert (sRef_inGlobalScope ());
10996 ue = uentry_makeVariableAux
10997 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
10998 sRef_makeGlobalMarker (),
11001 tloc = fileloc_createExternal ();
11002 uentry_setUsed (ue, tloc);
11003 uentry_setDefined (ue, tloc);
11004 fileloc_free (tloc);
11005 uentry_setHasNameError (ue);
11011 bool uentry_isGlobalMarker (uentry ue)
11013 return (uentry_isValid (ue)
11014 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11017 /* new start modifications */
11019 /* start modifications */
11021 requires: p_e is defined, is a ptr/array variable
11023 effects: sets the state of the variable
11027 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
11028 /*@access sRef@*/ /*i523 shouldn't do this! */
11029 if( uentry_isValid(p_e) ) {
11030 if( p_e->info != NULL) {
11031 if( p_e->info->var != NULL) {
11032 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11033 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11038 /*@noaccess sRef@*/
11040 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11044 requires: p_e is defined, is a ptr/array variable
11046 effects: sets the size of the buffer
11049 void uentry_setNullTerminatedState (uentry p_e) {
11050 if( uentry_isValid(p_e) ) {
11051 if( p_e->info != NULL) {
11052 if( p_e->info->var != NULL) {
11053 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11054 /*@access sRef@*/ /*@i523 bad!*/
11055 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11056 /*@noaccess sRef@*/
11062 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11066 requires: p_e is defined, is a ptr/array variable
11068 effects: sets the size of the buffer
11071 void uentry_setSize (uentry p_e, int size) {
11072 if( uentry_isValid(p_e) ) {
11073 if( p_e->info != NULL) {
11074 if( p_e->info->var != NULL) {
11075 p_e->info->var->bufinfo->size = size;
11076 /*@access sRef@*/ /*@i523 bad!*/
11077 p_e->sref->bufinfo.size = size;
11078 /*@noaccess sRef@*/
11084 fprintf(stderr, "uentry:Error in setSize\n");
11089 requires: p_e is defined, is a ptr/array variable
11091 effects: sets the length of the buffer
11094 void uentry_setLen (uentry p_e, int len) {
11095 if( uentry_isValid(p_e) ) {
11096 if( p_e->info != NULL) {
11097 if( p_e->info->var != NULL) {
11098 p_e->info->var->bufinfo->len = len;
11099 /*@access sRef@*/ /*@i523 bad!*/
11100 p_e->sref->bufinfo.len = len;
11101 /*@noaccess sRef@*/
11107 fprintf(stderr, "uentry:Error in setLen\n");
11112 bool uentry_hasMetaStateEnsures (uentry e)
11114 if (uentry_isValid (e) && uentry_isFunction (e))
11116 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11124 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11126 llassert (uentry_isValid (e) && uentry_isFunction (e));
11127 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);