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 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1440 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1444 static void uentry_addStateClause (uentry ue, stateClause sc)
1447 ** Okay to allow multiple clauses of the same kind.
1448 */ /*@i834 is this true?@*/
1450 ue->info->fcn->specclauses =
1451 stateClauseList_add (ue->info->fcn->specclauses, sc);
1453 /* Will call checkAll to check later... */
1456 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1458 llassert (uentry_isFunction (ue));
1459 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1461 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1462 ue->info->fcn->specclauses = clauses;
1463 stateClauseList_checkAll (ue);
1464 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1468 ** Used for @modifies@ @endmodifies@ syntax.
1470 ** If ue is specified, sr must contain *only*:
1472 ** o file static globals
1473 ** o sRef's derived from modifies spec (i.e., more specific than
1474 ** what was specified)
1476 ** Otherwise, if sr has modifies it must match sr.
1478 ** If it doesn't have modifies, set them to sr.
1482 uentry_checkModifiesContext (void)
1484 if (sRef_modInFunction ())
1488 ("Modifies list not in function context. "
1489 "A modifies list can only appear following the parameter list "
1490 "in a function declaration or header."));
1499 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1501 if (!uentry_checkModifiesContext ())
1507 if (uentry_isValid (ue))
1509 if (uentry_isIter (ue))
1511 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1512 ue->info->iter->mods = sr;
1516 uentry_convertVarFunction (ue);
1517 llassertfatal (uentry_isFunction (ue));
1518 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1520 ue->info->fcn->mods = sr;
1521 ue->info->fcn->hasMods = TRUE;
1523 checkGlobalsModifies (ue, sr);
1526 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1528 ue->info->fcn->hasGlobs = TRUE;
1531 if (sRefSet_hasStatic (ue->info->fcn->mods))
1533 context_recordFileModifies (ue->info->fcn->mods);
1543 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1546 ** Function already has one modifies clause (possibly from
1547 ** a specification).
1550 if (!uentry_checkModifiesContext ())
1555 llassert (uentry_isValid (ue));
1557 if (uentry_isIter (ue))
1559 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1563 llassertfatal (uentry_isFunction (ue));
1564 llassert (ue->info->fcn->hasMods);
1566 checkGlobalsModifies (ue, sr);
1567 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1569 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1571 ue->info->fcn->hasGlobs = TRUE;
1575 if (sRefSet_hasStatic (ue->info->fcn->mods))
1577 context_recordFileModifies (ue->info->fcn->mods);
1581 bool uentry_hasWarning (uentry ue)
1583 return (uentry_isValid (ue)
1584 && warnClause_isDefined (ue->warn));
1587 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1589 llassert (warnClause_isUndefined (ue->warn));
1594 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1596 if (sRef_modInFunction ())
1599 (message ("Precondition list not in function context. "
1600 "A precondition list can only appear following the parameter list "
1601 "in a function declaration or header."));
1603 /*@-mustfree@*/ return; /*@=mustfree@*/
1606 if (uentry_isValid (ue))
1608 uentry_convertVarFunction (ue);
1609 llassertfatal (uentry_isFunction (ue));
1611 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1613 BADBRANCH; /* should conjoin constraints? */
1615 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1619 ue->info->fcn->preconditions = preconditions;
1624 llfatalbug ( (message("uentry_setPreconditions called with invalid uentry") ));
1633 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1635 if (sRef_modInFunction ())
1638 (message ("Postcondition list not in function context. "
1639 "A postcondition list can only appear following the parameter list "
1640 "in a function declaration or header."));
1642 /*@-mustfree@*/ return; /*@=mustfree@*/
1645 if (uentry_isValid (ue))
1647 uentry_convertVarFunction (ue);
1648 llassertfatal (uentry_isFunction (ue));
1650 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1652 ue->info->fcn->postconditions = postconditions;
1656 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1661 llfatalbug ( (message("uentry_setPostconditions called with invalid uentry") ));
1666 ** requires: new and old are functions
1670 checkGlobalsConformance (/*@notnull@*/ uentry old,
1671 /*@notnull@*/ uentry unew,
1672 bool mustConform, bool completeConform)
1674 bool hasInternalState = FALSE;
1676 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1678 if (globSet_isDefined (unew->info->fcn->globs))
1680 globSet_allElements (unew->info->fcn->globs, el)
1682 if (sRef_isFileStatic (el))
1684 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1686 if (sRef_isInvalid (sr))
1688 bool hasError = FALSE;
1690 if (!hasInternalState
1691 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1692 sRef_makeInternalState ()))
1693 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1694 sRef_makeSpecState ())))
1697 && !uentry_isStatic (old)
1700 message ("Globals list for %q includes internal state, %q, "
1701 "but %s without globals internalState.",
1702 uentry_getName (old),
1704 uentry_specOrDefName (old)),
1705 uentry_whereLast (unew)))
1707 uentry_showWhereSpecified (old);
1711 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1712 sRef_makeInternalState ());
1713 hasInternalState = TRUE;
1717 && fileloc_sameFile (uentry_whereDeclared (unew),
1718 uentry_whereDeclared (old)))
1723 message ("Function %q inconsistently %rdeclared (in "
1724 "same file) with file static global %q in "
1726 uentry_getName (unew),
1727 uentry_isDeclared (old),
1729 uentry_whereDeclared (unew)))
1731 uentry_showWhereSpecified (old);
1736 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1737 context_recordFileGlobals (old->info->fcn->globs);
1741 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1743 if (sRef_isInvalid (sr))
1748 message ("Function %q inconsistently %rdeclared with "
1749 "%q in globals list",
1750 uentry_getName (unew),
1751 uentry_isDeclared (old),
1753 uentry_whereDeclared (unew)))
1755 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1756 uentry_showWhereSpecified (old);
1761 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1767 ("Function %q global %q inconsistently "
1768 "%rdeclared as %qout global",
1769 uentry_getName (unew),
1771 uentry_isDeclared (old),
1772 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1773 uentry_whereDeclared (unew)))
1775 uentry_showWhereSpecified (old);
1780 } end_globSet_allElements ;
1782 if (completeConform)
1784 globSet_allElements (old->info->fcn->globs, el)
1786 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1788 if (sRef_isInvalid (sr))
1791 && uentry_isReallySpecified (old)
1794 message ("Function %q specified with %q in globals list, "
1795 "but declared without %q",
1796 uentry_getName (unew),
1799 uentry_whereDeclared (unew)))
1801 uentry_showWhereSpecified (old);
1804 } end_globSet_allElements;
1809 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1811 if (uentry_isReallySpecified (old)
1814 message ("%s %q specified with globals list, but "
1815 "declared with no globals",
1816 ekind_capName (unew->ukind),
1817 uentry_getName (unew)),
1818 uentry_whereDeclared (unew)))
1821 (message ("Specification globals: %q",
1822 globSet_unparse (old->info->fcn->globs)),
1823 uentry_whereSpecified (old));
1827 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1828 old->info->fcn->globs);
1833 ** new modifies list must be included by old modifies list.
1835 ** file static state may be added to new, if old has internal.
1839 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1840 bool mustConform, bool completeConform)
1843 bool changedMods = FALSE;
1844 bool modInternal = FALSE;
1846 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1848 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1849 newMods = unew->info->fcn->mods;
1851 if (sRefSet_isEmpty (newMods))
1853 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1854 && uentry_isReallySpecified (old))
1858 message ("%s %q specified with modifies clause, "
1859 "but declared with no modifies clause",
1860 ekind_capName (unew->ukind),
1861 uentry_getName (unew)),
1862 uentry_whereDeclared (unew)))
1864 llgenindentmsg (message ("Specification has modifies %q",
1865 sRefSet_unparse (old->info->fcn->mods)),
1866 uentry_whereSpecified (old));
1873 sRefSet_allElements (newMods, current)
1875 if (sRef_isValid (current))
1877 sRef rb = sRef_getRootBase (current);
1879 if (sRef_isFileStatic (rb))
1883 if (!sRefSet_isSameMember (old->info->fcn->mods,
1884 sRef_makeInternalState ())
1885 && !sRefSet_isSameMember (old->info->fcn->mods,
1886 sRef_makeSpecState ()))
1889 && !uentry_isStatic (old)
1893 ("Modifies list for %q includes internal state, "
1894 "but %s without modifies internal.",
1895 uentry_getName (old),
1896 uentry_specOrDefName (old)),
1897 uentry_whereLast (unew)))
1899 uentry_showWhereSpecified (old);
1902 old->info->fcn->mods =
1903 sRefSet_insert (old->info->fcn->mods,
1904 sRef_makeInternalState ());
1909 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1915 if (sRef_canModifyVal (current, old->info->fcn->mods))
1917 int size = sRefSet_size (old->info->fcn->mods);
1919 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1922 if (sRefSet_size (old->info->fcn->mods) != size)
1933 ("Modifies list for %q contains %q, not modifiable "
1935 uentry_getName (old),
1936 sRef_unparse (current),
1937 uentry_specDeclName (old)),
1938 uentry_whereLast (unew)))
1940 uentry_showWhereSpecified (old);
1945 } end_sRefSet_allElements;
1947 if (completeConform && uentry_isReallySpecified (old))
1949 sRefSet_allElements (old->info->fcn->mods, el)
1951 if (sRef_canModify (el, newMods))
1960 ("Specification modifies clause for %q contains %q, "
1961 "not included in declaration modifies clause",
1962 uentry_getName (old),
1964 uentry_whereLast (unew)))
1966 uentry_showWhereSpecified (old);
1969 } end_sRefSet_allElements ;
1973 ** Make sure file static elements will be removed.
1978 context_recordFileModifies (old->info->fcn->mods);
1983 uentry_checkMutableType (uentry ue)
1985 ctype ct = uentry_getType (ue);
1987 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
1989 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
1991 voptgenerror (FLG_MUTREP,
1992 message ("Mutable abstract type %q declared without pointer "
1993 "indirection: %t (violates assignment semantics)",
1994 uentry_getName (ue), ct),
1995 uentry_whereDeclared (ue));
2000 uentry_setMutable (uentry e)
2002 llassert (uentry_isDatatype (e));
2003 e->info->datatype->mut = YES;
2007 uentry_checkIterArgs (uentry ue)
2009 bool hasYield = FALSE;
2012 llassert (uentry_isIter (ue));
2014 args = uentry_getParams (ue);
2016 uentryList_elements (args, el)
2018 sstate ds = uentry_getDefState (el);
2020 if (uentry_isYield (el))
2025 if (sstate_isUnknown (ds))
2027 uentry_setDefState (el, SS_DEFINED);
2033 } end_uentryList_elements;
2037 voptgenerror (FLG_HASYIELD,
2038 message ("Iterator %q declared with no yield parameters",
2039 uentry_getName (ue)),
2040 uentry_whereDeclared (ue));
2045 chkind_fromQual (qual qel)
2047 if (qual_isChecked (qel))
2051 else if (qual_isCheckMod (qel))
2055 else if (qual_isCheckedStrict (qel))
2057 return CH_CHECKEDSTRICT;
2059 else if (qual_isUnchecked (qel))
2061 return CH_UNCHECKED;
2066 /*@notreached@*/ return CH_UNKNOWN;
2071 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2073 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2075 if (!uentry_isRefCounted (ue))
2078 (FLG_ANNOTATIONERROR,
2079 message ("Reference counting qualifier %s used on non-reference "
2080 "counted storage: %q",
2082 uentry_unparse (ue)),
2083 uentry_whereLast (ue));
2087 alkind ak = alkind_fromQual (qel);
2089 uentry_setAliasKind (ue, ak);
2092 else if (qual_isRefCounted (qel))
2094 ctype ct = ctype_realType (uentry_getType (ue));
2097 if (ctype_isPointer (ct)
2098 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2100 /* check there is a refs field */
2101 uentryList fields = ctype_getFields (rt);
2102 uentry refs = uentry_undefined;
2104 uentryList_elements (fields, field)
2106 if (uentry_isRefsField (field))
2108 if (uentry_isValid (refs))
2111 (FLG_ANNOTATIONERROR,
2112 message ("Reference counted structure type %s has "
2113 "multiple refs fields: %q and %q",
2115 uentry_getName (refs),
2116 uentry_getName (field)),
2117 uentry_whereLast (field));
2122 } end_uentryList_elements;
2124 if (uentry_isInvalid (refs))
2128 message ("Reference counted structure type %s has "
2130 ctype_unparse (ct)),
2132 ("To count reference, the structure must have a field named "
2133 "refs of type int."),
2136 else if (!ctype_isInt (uentry_getType (refs)))
2139 (FLG_ANNOTATIONERROR,
2140 message ("Reference counted structure type %s refs field has "
2141 "type %s (should be int)", ctype_unparse (ct),
2142 ctype_unparse (uentry_getType (refs))),
2143 uentry_whereLast (refs));
2147 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2148 uentry_whereDeclared (ue));
2153 if ((ctype_isPointer (ct)
2154 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2155 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2157 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2158 uentry_whereDeclared (ue));
2163 (FLG_ANNOTATIONERROR,
2164 message ("Non-pointer to structure type %s declared with "
2165 "refcounted qualifier",
2166 ctype_unparse (ct)),
2167 uentry_whereLast (ue));
2171 else if (qual_isRefs (qel))
2173 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2175 uentry_setAliasKind (ue, AK_REFS);
2180 (FLG_ANNOTATIONERROR,
2181 message ("Refs qualifier used on non-structure field: %q",
2182 uentry_unparse (ue)),
2183 uentry_whereLast (ue));
2186 else if (qual_isAliasQual (qel))
2188 alkind ak = alkind_fromQual (qel);
2190 alkind oldak = uentry_getAliasKind (ue);
2191 ctype ut = uentry_getType (ue);
2193 if (alkind_isImplicit (ak)
2194 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2196 /* ignore the implied qualifier */
2200 if (uentry_isEitherConstant (ue))
2203 (FLG_ANNOTATIONERROR,
2204 message ("Alias qualifier %s used on constant: %q",
2205 alkind_unparse (ak), uentry_unparse (ue)),
2206 uentry_whereLast (ue));
2211 if (ctype_isFunction (ut))
2213 ut = ctype_getReturnType (ut);
2216 if (!(ctype_isVisiblySharable (ut)
2217 || ctype_isRealArray (ut)
2218 || ctype_isRealSU (ut)))
2220 if (!qual_isImplied (qel))
2223 (FLG_ANNOTATIONERROR,
2224 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2225 alkind_unparse (ak), ut, uentry_getName (ue)),
2226 uentry_whereLast (ue));
2233 if (uentry_isRefCounted (ue))
2235 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2236 || qual_isExposed (qel)
2237 || qual_isObserver (qel)))
2239 if (!qual_isImplied (qel))
2242 (FLG_ANNOTATIONERROR,
2244 ("Alias qualifier %s used on reference counted storage: %q",
2245 alkind_unparse (ak),
2246 uentry_unparse (ue)),
2247 uentry_whereLast (ue));
2255 if (qual_isRefQual (qel))
2258 (FLG_ANNOTATIONERROR,
2259 message ("Qualifier %s used on non-reference counted storage: %q",
2260 alkind_unparse (ak), uentry_unparse (ue)),
2261 uentry_whereLast (ue));
2270 uentry_setAliasKind (ue, ak);
2273 else if (qual_isNull (qel))
2275 if (uentry_isConstant (ue))
2279 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2280 uentry_whereDeclared (ue));
2284 uentry_setNullState (ue, NS_POSNULL);
2287 else if (qual_isRelNull (qel))
2289 uentry_setNullState (ue, NS_RELNULL);
2291 else if (qual_isNotNull (qel))
2293 uentry_setNullState (ue, NS_MNOTNULL);
2295 else if (qual_isAbstract (qel)
2296 || qual_isConcrete (qel))
2298 if (!uentry_isDatatype (ue))
2301 (FLG_ANNOTATIONERROR,
2302 message ("Qualifier %s used with non-datatype",
2303 qual_unparse (qel)),
2304 uentry_whereLast (ue));
2308 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2311 else if (qual_isMutable (qel))
2313 if (!uentry_isDatatype (ue))
2316 (FLG_ANNOTATIONERROR,
2317 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2318 uentry_whereLast (ue));
2322 if (!ynm_isOn (ue->info->datatype->mut))
2324 uentry_checkMutableType (ue);
2327 ue->info->datatype->mut = YES;
2330 else if (qual_isImmutable (qel))
2332 if (!uentry_isDatatype (ue))
2334 voptgenerror (FLG_ANNOTATIONERROR,
2335 message ("Qualifier %s used with non-datatype",
2336 qual_unparse (qel)),
2337 uentry_whereLast (ue));
2341 ue->info->datatype->mut = NO;
2344 else if (qual_isNullPred (qel))
2346 uentry_convertVarFunction (ue);
2348 if (uentry_isFunction (ue))
2350 ctype typ = uentry_getType (ue);
2351 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2353 if (ctype_isRealBool (rtype))
2355 uentryList pl = ctype_argsFunction (typ);
2357 if (uentryList_size (pl) == 1)
2359 ue->info->fcn->nullPred = qel;
2363 voptgenerror (FLG_ANNOTATIONERROR,
2364 message ("Qualifier %s used with function having %d "
2365 "arguments (should have 1)",
2367 uentryList_size (pl)),
2368 uentry_whereLast (ue));
2373 voptgenerror (FLG_ANNOTATIONERROR,
2374 message ("Qualifier %s used with function returning %s "
2375 "(should return bool)",
2377 ctype_unparse (rtype)),
2378 uentry_whereLast (ue));
2383 voptgenerror (FLG_ANNOTATIONERROR,
2384 message ("Qualifier %s used with non-function",
2385 qual_unparse (qel)),
2386 uentry_whereLast (ue));
2389 else if (qual_isExitQual (qel))
2391 exitkind exk = exitkind_fromQual (qel);
2393 if (uentry_isFunction (ue))
2395 if (exitkind_isKnown (ue->info->fcn->exitCode))
2397 voptgenerror (FLG_ANNOTATIONERROR,
2398 message ("Multiple exit qualifiers used on function %q: %s, %s",
2399 uentry_getName (ue),
2400 exitkind_unparse (ue->info->fcn->exitCode),
2401 exitkind_unparse (exk)),
2402 uentry_whereLast (ue));
2405 ue->info->fcn->exitCode = exk;
2409 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2411 uentry_makeVarFunction (ue);
2412 ue->info->fcn->exitCode = exk;
2416 voptgenerror (FLG_ANNOTATIONERROR,
2417 message ("Exit qualifier %s used with non-function (type %s)",
2419 ctype_unparse (uentry_getType (ue))),
2420 uentry_whereLast (ue));
2424 else if (qual_isMetaState (qel))
2426 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2428 if (annotationInfo_matchesContext (ainfo, ue))
2430 DPRINTF (("Reflecting %s on %s",
2431 annotationInfo_unparse (ainfo),
2432 uentry_unparseFull (ue)));
2434 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2435 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2436 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2441 (FLG_ANNOTATIONERROR,
2442 message ("Meta state annotation %s used in inconsistent context: %q",
2444 uentry_unparse (ue)),
2445 uentry_whereLast (ue)))
2447 /*@i! annotationInfo_showContextError (ainfo, ue); */
2453 if (qual_isCQual (qel))
2459 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2465 uentry_reflectQualifiers (uentry ue, qualList q)
2467 llassert (uentry_isValid (ue));
2469 DPRINTF (("Reflect qualifiers: %s / %s",
2470 uentry_unparseFull (ue), qualList_unparse (q)));
2472 qualList_elements (q, qel)
2474 if (qual_isStatic (qel))
2476 uentry_setStatic (ue);
2478 else if (qual_isUnused (qel))
2480 uentry_setUsed (ue, fileloc_undefined);
2482 else if (qual_isExternal (qel))
2484 fileloc_free (ue->whereDefined);
2485 ue->whereDefined = fileloc_createExternal ();
2487 else if (qual_isSef (qel))
2489 if (uentry_isVariable (ue))
2491 vkind vk = ue->info->var->kind;
2493 llassert (vk != VKREFPARAM);
2495 if (vk == VKYIELDPARAM)
2498 (FLG_ANNOTATIONERROR,
2499 message ("Qualifier sef cannot be used with %s: %q",
2500 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2501 uentry_unparse (ue)),
2502 uentry_whereLast (ue));
2504 else if (vk == VKRETPARAM)
2506 ue->info->var->kind = VKSEFRETPARAM;
2510 ue->info->var->kind = VKSEFPARAM;
2516 (FLG_ANNOTATIONERROR,
2517 message ("Qualifier sef is meaningful only on parameters: %q",
2518 uentry_unparse (ue)),
2519 uentry_whereLast (ue));
2522 else if (qual_isExtern (qel))
2524 ue->storageclass = SCEXTERN;
2526 else if (qual_isGlobalQual (qel)) /* undef, killed */
2528 DPRINTF (("Reflecting qual: %s / %s",
2529 qual_unparse (qel), uentry_unparse (ue)));
2531 if (uentry_isVariable (ue))
2533 sstate oldstate = ue->info->var->defstate;
2534 sstate defstate = sstate_fromQual (qel);
2537 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2538 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2540 defstate = SS_UNDEFKILLED;
2547 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2548 ue->info->var->defstate = defstate;
2553 (FLG_ANNOTATIONERROR,
2554 message ("Qualifier %s used on non-variable: %q",
2555 qual_unparse (qel), uentry_unparse (ue)),
2556 uentry_whereLast (ue));
2559 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2561 /* start modifications */
2562 else if( qual_isBufQualifier(qel) ) {
2563 ctype ct = ctype_realType(uentry_getType(ue));
2564 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2566 if( uentry_hasBufStateInfo(ue) ) {
2567 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2569 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2570 /* If formal func param */
2571 uentry_setNullTerminatedState(ue);
2572 uentry_setLen (ue, 1);
2573 uentry_setSize (ue, 1);
2575 sRef_setNullTerminatedState(uentry_getSref(ue));
2576 sRef_setLen (uentry_getSref(ue), 1);
2577 sRef_setSize (uentry_getSref(ue), 1);
2579 uentry_setPossiblyNullTerminatedState(ue);
2581 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2585 /* put other BufState Qualifiers here */
2587 cstring s = uentry_getName(ue);
2588 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2589 struct for identifier %s\n", s) );
2591 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2593 sRef retSref = uentry_getSref (ue);
2594 ctype retType = sRef_getType (retSref);
2596 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2597 sRef_setNullTerminatedState (retSref);
2603 message ("Qualifier %s used on non-pointer on \
2604 function return: %q", qual_unparse (qel),
2605 uentry_unparse (ue)));
2612 message ("Qualifier %s used on non-pointer: %q",
2613 qual_unparse (qel), uentry_unparse (ue)));
2615 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2617 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2619 ctype realType = ctype_realType (ue->utype);
2620 sstate defstate = sstate_fromQual (qel);
2622 if (ctype_isFunction (realType))
2624 realType = ctype_realType (ctype_getReturnType (realType));
2627 if (qual_isRelDef (qel))
2629 ; /* okay anywhere */
2633 if (!ctype_isAP (realType)
2634 && !ctype_isSU (realType)
2635 && !ctype_isUnknown (realType)
2636 && !ctype_isAbstract (ue->utype))
2639 (FLG_ANNOTATIONERROR,
2640 message ("Qualifier %s used on non-pointer or struct: %q",
2641 qual_unparse (qel), uentry_unparse (ue)),
2642 uentry_whereLast (ue));
2646 uentry_setDefState (ue, defstate);
2648 if (sRef_isStateSpecial (ue->sref)
2649 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2651 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2654 else if (qual_isYield (qel))
2656 if (uentry_isVariable (ue))
2658 ue->info->var->kind = VKYIELDPARAM;
2663 (FLG_ANNOTATIONERROR,
2664 message ("Qualifier %s used on non-iterator parameter: %q",
2665 qual_unparse (qel), uentry_unparse (ue)),
2666 uentry_whereLast (ue));
2669 else if (qual_isExQual (qel))
2671 exkind ek = exkind_fromQual (qel);
2672 ctype ut = uentry_getType (ue);
2674 DPRINTF (("Reflect ex qual: %s / %s",
2675 uentry_unparse (ue), exkind_unparse (ek)));
2677 if (ctype_isFunction (ut))
2679 ut = ctype_getReturnType (ut);
2682 if (!(ctype_isVisiblySharable (ut))
2683 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2684 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2686 if (!qual_isImplied (qel))
2688 if (ctype_isImmutableAbstract (ut)) {
2690 (FLG_REDUNDANTSHAREQUAL,
2691 message ("Qualifier %s used on unsharable storage type %t: %q",
2692 exkind_unparse (ek), ut, uentry_getName (ue)),
2693 uentry_whereLast (ue));
2696 (FLG_MISPLACEDSHAREQUAL,
2697 message ("Qualifier %s used on unsharable storage type %t: %q",
2698 exkind_unparse (ek), ut, uentry_getName (ue)),
2699 uentry_whereLast (ue));
2705 alkind ak = sRef_getAliasKind (ue->sref);
2707 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2708 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2710 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2712 if (!alkind_isTemp (ak))
2714 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2715 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2718 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2719 || alkind_isOwned (ak))
2727 message ("Exposure qualifier %s used on %s storage (should "
2728 "be dependent): %q",
2730 alkind_unparse (ak),
2731 uentry_unparse (ue)));
2735 else if (qual_isGlobCheck (qel))
2737 if (uentry_isVariable (ue))
2739 chkind ch = chkind_fromQual (qel);
2741 if (ue->info->var->checked != CH_UNKNOWN)
2743 if (ch == ue->info->var->checked)
2745 llerror (FLG_SYNTAX,
2746 message ("Redundant %s qualifier on %q",
2748 uentry_getName (ue)));
2752 llerror (FLG_SYNTAX,
2754 ("Contradictory %s and %s qualifiers on %q",
2756 checkedName (ue->info->var->checked),
2757 uentry_getName (ue)));
2761 ue->info->var->checked = ch;
2767 message ("Qualifier %s used with non-variable",
2768 qual_unparse (qel)));
2771 else if (qual_isReturned (qel))
2773 if (uentry_isVariable (ue))
2775 ue->info->var->kind = VKRETPARAM;
2779 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2780 qual_unparse (qel)));
2785 uentry_reflectOtherQualifier (ue, qel);
2788 sRef_storeState (ue->sref);
2789 } end_qualList_elements;
2793 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2797 uentry_isOnly (uentry ue)
2799 return (!uentry_isUndefined (ue)
2800 && uentry_isVariable (ue)
2801 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2805 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2807 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2808 sRef_setOrigAliasKind (ue->sref, ak);
2812 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2814 if (uentry_isVariable (ue))
2816 ue->info->var->nullstate = ns;
2819 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2823 uentry_isUnique (uentry ue)
2825 return (!uentry_isUndefined (ue)
2826 && uentry_isVariable (ue)
2827 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2831 uentry_isFileStatic (uentry ue)
2833 return (uentry_isStatic (ue)
2834 && (!uentry_isVariable (ue)
2835 || sRef_isFileStatic (uentry_getSref (ue))));
2839 uentry_isExported (uentry ue)
2841 if (uentry_isValid (ue))
2843 if (uentry_isVariable (ue))
2845 return (sRef_isRealGlobal (uentry_getSref (ue)));
2849 return !uentry_isStatic (ue);
2857 uentry_isNonLocal (uentry ue)
2859 return (uentry_isValid (ue) && uentry_isVariable (ue)
2860 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2864 uentry_isGlobalVariable (uentry ue)
2866 return (uentry_isValid (ue) && uentry_isVariable (ue)
2867 && sRef_isFileOrGlobalScope (ue->sref));
2871 uentry_isVisibleExternally (uentry ue)
2873 return (uentry_isValid (ue)
2874 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2875 || (!uentry_isStatic (ue)
2876 && (uentry_isFunction (ue)
2877 || uentry_isIter (ue)
2878 || uentry_isEndIter (ue)
2879 || uentry_isConstant (ue)
2880 || uentry_isDatatype (ue)
2881 || uentry_isAnyTag (ue)))));
2885 uentry_isPrintfLike (uentry ue)
2887 return (uentry_isFunction (ue)
2888 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2892 uentry_isScanfLike (uentry ue)
2894 return (uentry_isFunction (ue)
2895 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2899 uentry_isMessageLike (uentry ue)
2901 return (uentry_isFunction (ue)
2902 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2905 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2907 uentryList args = uentry_getParams (ue);
2909 if (!uentryList_isMissingParams (args))
2911 uentry last = uentry_undefined;
2913 uentryList_elements (args, current)
2915 if (uentry_isElipsisMarker (current))
2917 if (uentry_isUndefined (last))
2921 message ("Function %q is marked %s, but has no format "
2922 "string argument before elipsis",
2923 uentry_getName (ue),
2924 specCode_unparse (ue->info->fcn->specialCode)),
2925 uentry_whereLast (ue));
2926 ue->info->fcn->specialCode = SPC_NONE;
2930 ctype rt = ctype_realType (uentry_getType (last));
2932 if (!ctype_match (rt, ctype_string))
2936 /* wchar_t * is okay too */
2937 if (ctype_isAP (rt))
2939 ctype base = ctype_baseArrayPtr (rt);
2941 if (ctype_isArbitraryIntegral (base))
2951 message ("Function %q is marked %s, but the argument "
2952 "before the elipsis has type %s (should be char *)",
2953 uentry_getName (ue),
2954 specCode_unparse (ue->info->fcn->specialCode),
2955 ctype_unparse (uentry_getType (last))),
2956 uentry_whereLast (ue));
2958 ue->info->fcn->specialCode = SPC_NONE;
2965 } end_uentryList_elements ;
2969 message ("Function %q is marked %s, but has no elipsis parameter",
2970 uentry_getName (ue),
2971 specCode_unparse (ue->info->fcn->specialCode)),
2972 uentry_whereLast (ue));
2974 ue->info->fcn->specialCode = SPC_NONE;
2979 uentry_setPrintfLike (uentry ue)
2981 uentry_convertVarFunction (ue);
2982 llassertfatal (uentry_isFunction (ue));
2983 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2984 checkSpecialFunction (ue);
2988 uentry_setScanfLike (uentry ue)
2990 uentry_convertVarFunction (ue);
2991 llassertfatal (uentry_isFunction (ue));
2992 ue->info->fcn->specialCode = SPC_SCANFLIKE;
2993 checkSpecialFunction (ue);
2997 uentry_setMessageLike (uentry ue)
2999 uentry_convertVarFunction (ue);
3000 llassertfatal (uentry_isFunction (ue));
3001 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3002 checkSpecialFunction (ue);
3006 uentry_isSpecialFunction (uentry ue)
3008 return (uentry_isFunction (ue)
3009 && (ue->info->fcn->specialCode != SPC_NONE));
3012 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3014 ctype ct = idDecl_getCtype (t);
3016 fileloc loc = setLocation ();
3017 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3018 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3020 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3021 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3022 uentry_implicitParamAnnots (ue);
3024 /* Parameter type [][] or [x][] is invalid */
3026 while (ctype_isFixedArray (base)) {
3027 base = ctype_baseArrayPtr (base);
3030 if (ctype_isIncompleteArray (base)) {
3031 base = ctype_baseArrayPtr (base);
3033 if (ctype_isArray (base)) {
3034 if (!uentry_hasName (ue)) {
3035 (void) optgenerror (FLG_INCOMPLETETYPE,
3036 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3038 ctype_unparse (ct)),
3039 uentry_whereLast (ue));
3041 (void) optgenerror (FLG_INCOMPLETETYPE,
3042 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3043 uentry_getName (ue),
3044 ctype_unparse (ct)),
3045 uentry_whereLast (ue));
3050 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3054 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3056 ctype ct = idDecl_getCtype (t);
3058 if (ctype_isFunction (ct))
3060 return (uentry_makeIdFunction (t));
3064 fileloc loc = setLocation ();
3065 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3067 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3069 if (!uentry_isExtern (ue))
3071 uentry_setDefined (ue, loc);
3079 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3081 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3089 /*@only@*/ /*@notnull@*/
3090 uentry uentry_makeConstantAux (cstring n, ctype t,
3091 /*@keep@*/ fileloc f, bool priv,
3092 /*@only@*/ multiVal m)
3094 uentry e = uentry_alloc ();
3097 e->uname = cstring_copy (n);
3099 e->storageclass = SCNONE;
3101 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3103 e->sref = sRef_makeConst (t);
3108 e->uses = filelocList_new ();
3109 e->isPrivate = priv;
3110 e->hasNameError = FALSE;
3112 e->info = (uinfo) dmalloc (sizeof (*e->info));
3113 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3114 e->info->uconst->access = typeIdSet_undefined;
3116 uentry_setSpecDef (e, f);
3118 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3120 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3123 uentry_setConstantValue (e, m);
3128 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3130 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
3133 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3135 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3136 idDecl_getCtype (t),
3139 llassert (fileloc_isUndefined (ue->whereDeclared));
3140 ue->whereDeclared = setLocation ();
3141 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3143 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3151 void uentry_setDefState (uentry ue, sstate defstate)
3153 if (uentry_isValid (ue))
3155 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3157 if (uentry_isVariable (ue))
3159 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3164 bool uentry_isCheckedUnknown (uentry ue)
3166 return (uentry_isVar (ue)
3167 && (ue->info->var->checked == CH_UNKNOWN));
3170 bool uentry_isCheckMod (uentry ue)
3172 return (uentry_isVar (ue)
3173 && (ue->info->var->checked == CH_CHECKMOD));
3176 bool uentry_isUnchecked (uentry ue)
3178 return (uentry_isVar (ue)
3179 && (ue->info->var->checked == CH_UNCHECKED));
3182 bool uentry_isChecked (uentry ue)
3184 return (uentry_isVar (ue)
3185 && (ue->info->var->checked == CH_CHECKED));
3188 bool uentry_isCheckedModify (uentry ue)
3190 return (uentry_isVar (ue)
3191 && (ue->info->var->checked == CH_CHECKED
3192 || ue->info->var->checked == CH_CHECKMOD
3193 || ue->info->var->checked == CH_CHECKEDSTRICT));
3196 bool uentry_isCheckedStrict (uentry ue)
3198 return (uentry_isVar (ue)
3199 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3202 void uentry_setUnchecked (uentry ue)
3204 llassert (uentry_isVar (ue));
3206 ue->info->var->checked = CH_UNCHECKED;
3209 void uentry_setChecked (uentry ue)
3211 llassert (uentry_isVar (ue));
3213 ue->info->var->checked = CH_CHECKED;
3216 void uentry_setCheckMod (uentry ue)
3218 llassert (uentry_isVar (ue));
3220 ue->info->var->checked = CH_CHECKMOD;
3223 void uentry_setCheckedStrict (uentry ue)
3225 llassert (uentry_isVar (ue));
3227 ue->info->var->checked = CH_CHECKEDSTRICT;
3230 static /*@only@*/ /*@notnull@*/
3231 uentry uentry_makeVariableAux (cstring n, ctype t,
3233 /*@exposed@*/ sRef s,
3234 bool priv, vkind kind)
3236 uentry e = uentry_alloc ();
3239 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3242 e->uname = cstring_copy (n);
3245 e->storageclass = SCNONE;
3247 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3254 e->uses = filelocList_new ();
3255 e->isPrivate = priv;
3256 e->hasNameError = FALSE;
3258 e->info = (uinfo) dmalloc (sizeof (*e->info));
3259 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3260 e->info->var->kind = kind;
3262 e->info->var->checked = CH_UNKNOWN;
3264 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3265 uentry_setSpecDef (e, f);
3266 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3268 if (ctype_isFunction (rt))
3270 rt = ctype_getReturnType (rt);
3273 if (ctype_isUA (rt))
3275 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3276 sRef_setStateFromType (e->sref, rt);
3279 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3280 e->info->var->defstate = sRef_getDefState (e->sref);
3281 e->info->var->nullstate = sRef_getNullState (e->sref);
3283 /* start modifications */
3284 /* This function sets the uentry for a pointer or array variable declaration,
3285 it allocates memory and sets the fields. We check if the type of the variable
3286 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3288 if( ctype_isArray (t) || ctype_isPointer(t)) {
3289 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3290 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3291 /*@access sRef@*/ /*i@222*/
3292 /* It probably isn't necessary to violate the abstraction here
3295 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
3298 e->info->var->bufinfo = NULL;
3300 /* end modification */
3306 uentry_isYield (uentry ue)
3308 return (uentry_isVariable (ue)
3309 && (ue->info->var->kind == VKYIELDPARAM
3310 || ue->info->var->kind == VKREFYIELDPARAM));
3314 uentry_isRefsField (uentry ue)
3316 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3319 /*@only@*/ /*@notnull@*/
3320 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3322 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3323 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3330 void uentry_makeVarFunction (uentry ue)
3337 llassert (uentry_isValid (ue));
3338 llassert (!sRef_modInFunction ());
3340 ak = sRef_getOrigAliasKind (ue->sref);
3341 ek = sRef_getOrigExKind (ue->sref);
3343 llassert (uentry_isVariable (ue));
3344 oldInfo = ue->info->var;
3346 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3349 ** expanded macro is marked used (until I write a pre-processor)
3352 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3355 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3356 ue->info->fcn->exitCode = XK_UNKNOWN;
3357 ue->info->fcn->nullPred = qual_createUnknown ();
3358 ue->info->fcn->specialCode = SPC_NONE;
3359 ue->info->fcn->access = typeIdSet_undefined;
3360 ue->info->fcn->hasGlobs = FALSE;
3361 ue->info->fcn->globs = globSet_undefined;
3362 ue->info->fcn->hasMods = FALSE;
3363 ue->info->fcn->mods = sRefSet_undefined;
3364 ue->info->fcn->specclauses = NULL;
3365 ue->info->fcn->defparams = uentryList_undefined;
3368 ue->info->fcn->preconditions = functionConstraint_undefined;
3372 ue->info->fcn->postconditions = functionConstraint_undefined;
3375 if (ctype_isFunction (ue->utype))
3377 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3381 ue->sref = sRef_makeType (ctype_unknown);
3384 if (sRef_isRefCounted (ue->sref))
3390 if (alkind_isUnknown (ak))
3392 if (exkind_isKnown (ek))
3394 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3395 ak = AK_IMPDEPENDENT;
3399 if (context_getFlag (FLG_RETIMPONLY))
3401 if (ctype_isFunction (ue->utype)
3402 && ctype_isVisiblySharable
3403 (ctype_realType (ctype_getReturnType (ue->utype))))
3405 if (uentryList_hasReturned (uentry_getParams (ue)))
3411 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3426 loc = ue->whereDeclared;
3428 sRef_setAliasKind (ue->sref, ak, loc);
3429 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3430 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3431 sRef_setExKind (ue->sref, ek, loc);
3433 if (oldInfo->kind == VKEXPMACRO)
3439 fileloc_free (ue->whereDefined);
3440 ue->whereDefined = fileloc_undefined;
3443 uvinfo_free (oldInfo);
3446 void uentry_makeConstantFunction (uentry ue)
3453 llassert (uentry_isValid (ue));
3454 llassert (!sRef_modInFunction ());
3456 ak = sRef_getOrigAliasKind (ue->sref);
3457 ek = sRef_getOrigExKind (ue->sref);
3459 llassert (uentry_isConstant (ue));
3460 oldInfo = ue->info->uconst;
3462 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3465 ** expanded macro is marked used (until I write a pre-processor)
3469 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3470 ue->info->fcn->exitCode = XK_UNKNOWN;
3471 ue->info->fcn->nullPred = qual_createUnknown ();
3472 ue->info->fcn->specialCode = SPC_NONE;
3473 ue->info->fcn->access = typeIdSet_undefined;
3474 ue->info->fcn->hasGlobs = FALSE;
3475 ue->info->fcn->globs = globSet_undefined;
3476 ue->info->fcn->hasMods = FALSE;
3477 ue->info->fcn->mods = sRefSet_undefined;
3478 ue->info->fcn->specclauses = NULL;
3479 ue->info->fcn->defparams = uentryList_undefined;
3482 ue->info->fcn->preconditions = functionConstraint_undefined;
3486 ue->info->fcn->postconditions = functionConstraint_undefined;
3490 if (ctype_isFunction (ue->utype))
3492 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3496 ue->sref = sRef_makeType (ctype_unknown);
3499 if (sRef_isRefCounted (ue->sref))
3505 if (alkind_isUnknown (ak))
3507 if (exkind_isKnown (ek))
3509 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3510 ak = AK_IMPDEPENDENT;
3514 if (context_getFlag (FLG_RETIMPONLY))
3516 if (ctype_isFunction (ue->utype)
3517 && ctype_isVisiblySharable
3518 (ctype_realType (ctype_getReturnType (ue->utype))))
3520 if (uentryList_hasReturned (uentry_getParams (ue)))
3526 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3541 loc = ue->whereDeclared;
3543 sRef_setAliasKind (ue->sref, ak, loc);
3544 sRef_setExKind (ue->sref, ek, loc);
3546 fileloc_free (ue->whereDefined);
3547 ue->whereDefined = fileloc_undefined;
3548 ucinfo_free (oldInfo);
3552 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3554 llassert (uentry_isValid (ue));
3556 if (uentry_isIter (ue))
3558 llassert (globSet_isUndefined (ue->info->iter->globs));
3559 ue->info->iter->globs = globs;
3563 uentry_convertVarFunction (ue);
3565 llassert (uentry_isFunction (ue));
3566 llassert (!ue->info->fcn->hasGlobs
3567 && globSet_isUndefined (ue->info->fcn->globs));
3569 ue->info->fcn->hasGlobs = TRUE;
3570 globSet_markImmutable (globs);
3571 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3576 if (globSet_hasStatic (globs))
3578 context_recordFileGlobals (globs);
3582 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3584 ue->info->fcn->hasMods = TRUE;
3588 void uentry_addAccessType (uentry ue, typeId tid)
3590 if (uentry_isFunction (ue))
3592 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3594 else if (uentry_isEitherConstant (ue))
3596 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3598 else if (uentry_isIter (ue))
3600 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3602 else if (uentry_isEndIter (ue))
3604 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3608 llbug (message ("no access for: %q", uentry_unparse (ue)));
3612 /*@only@*/ /*@notnull@*/ uentry
3613 uentry_makeFunction (cstring n, ctype t,
3615 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3616 /*@only@*/ warnClause warn,
3619 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3620 return (uentry_makeFunctionAux (n, t,
3621 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3622 : typeIdSet_single (access)),
3629 /*@notnull@*/ uentry
3630 uentry_makePrivFunction2 (cstring n, ctype t,
3632 globSet globs, sRefSet mods,
3635 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3640 /*@notnull@*/ uentry
3641 uentry_makeSpecFunction (cstring n, ctype t,
3643 /*@only@*/ globSet globs,
3644 /*@only@*/ sRefSet mods,
3647 uentry ue = uentry_makeFunctionAux (n, t, access,
3648 globs, mods, warnClause_undefined,
3651 uentry_setHasGlobs (ue);
3652 uentry_setHasMods (ue);
3654 reflectImplicitFunctionQualifiers (ue, TRUE);
3659 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3661 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3662 sRef_undefined, FALSE, VKEXPMACRO);
3664 uentry_setDefined (ue, f);
3668 /*@notnull@*/ /*@notnull@*/ uentry
3669 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3671 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3672 typeIdSet_singleOpt (access),
3673 globSet_undefined, sRefSet_undefined,
3674 warnClause_undefined,
3678 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3682 bool uentry_isForward (uentry e)
3684 if (uentry_isValid (e))
3686 ctype ct = uentry_getType (e);
3688 return (ctype_isUnknown (ct)
3689 || (ctype_isFunction (ct)
3690 && ctype_isUnknown (ctype_getReturnType (ct))));
3697 /*@notnull@*/ uentry
3698 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3700 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3701 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3705 /*@notnull@*/ uentry
3706 uentry_makeUnspecFunction (cstring n, ctype t,
3710 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3711 sRefSet_undefined, warnClause_undefined,
3714 reflectImplicitFunctionQualifiers (ue, TRUE);
3723 /* is exported for use by usymtab_interface */
3725 /*@notnull@*/ uentry
3726 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3727 fileloc f, bool priv)
3729 uentry e = uentry_alloc ();
3731 DPRINTF (("Make datatype: %s / %s",
3732 n, ctype_unparse (t)));
3734 /* e->shallowCopy = FALSE; */
3735 e->ukind = KDATATYPE;
3736 e->uname = cstring_copy (n);
3738 e->storageclass = SCNONE;
3739 e->sref = sRef_makeUnknown ();
3743 sRef_setStateFromType (e->sref, t);
3746 uentry_setSpecDef (e, f);
3748 e->warn = warnClause_undefined; /*@i634@*/
3749 e->uses = filelocList_new ();
3750 e->isPrivate = priv;
3751 e->hasNameError = FALSE;
3756 e->info = (uinfo) dmalloc (sizeof (*e->info));
3757 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3758 e->info->datatype->abs = abstract;
3759 e->info->datatype->mut = mut;
3760 e->info->datatype->type = ctype_undefined;
3762 if (uentry_isDeclared (e))
3764 uentry_setDefined (e, f);
3767 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3769 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3775 /*@notnull@*/ uentry
3776 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3778 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3781 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3783 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3784 ctype_bool, NO, abstract,
3785 fileloc_getBuiltin (),
3788 ret->info->datatype->type = ctype_bool;
3796 static /*@only@*/ /*@notnull@*/ uentry
3797 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3798 /*@only@*/ fileloc f)
3800 uentry e = uentry_alloc ();
3803 e->uname = cstring_copy (n);
3805 e->sref = sRef_makeUnknown ();
3806 e->storageclass = SCNONE;
3810 uentry_setSpecDef (e, f);
3812 e->warn = warnClause_undefined; /*@i452@*/
3813 e->uses = filelocList_new ();
3814 e->isPrivate = FALSE;
3815 e->hasNameError = FALSE;
3817 e->info = (uinfo) dmalloc (sizeof (*e->info));
3818 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3819 e->info->iter->access = access;
3820 e->info->iter->mods = sRefSet_undefined;
3821 e->info->iter->globs = globSet_undefined;
3823 uentry_checkIterArgs (e);
3827 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3829 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3832 static /*@notnull@*/ uentry
3833 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3835 uentry e = uentry_alloc ();
3837 /* e->shallowCopy = FALSE; */
3838 e->ukind = KENDITER;
3839 e->storageclass = SCNONE;
3840 e->uname = message ("end_%s", n);
3841 e->utype = ctype_unknown;
3842 e->sref = sRef_makeUnknown ();
3844 uentry_setSpecDef (e, f);
3849 e->uses = filelocList_new ();
3850 e->isPrivate = FALSE;
3851 e->hasNameError = FALSE;
3853 e->info = (uinfo) dmalloc (sizeof (*e->info));
3854 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3856 e->info->enditer->access = access;
3858 e->warn = warnClause_undefined; /*@i452@*/
3862 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3864 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3871 static /*@only@*/ /*@notnull@*/ uentry
3872 uentry_makeTagAux (cstring n, ctype t,
3873 /*@only@*/ fileloc fl,
3874 bool priv, ekind kind)
3876 uentry e = uentry_alloc ();
3878 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3880 llbuglit ("uentry_makeTagAux: not a tag type");
3884 /* e->shallowCopy = FALSE; */
3885 e->uname = cstring_copy (n);
3888 e->sref = sRef_makeUnknown ();
3889 e->storageclass = SCNONE;
3891 uentry_setSpecDef (e, fl);
3896 e->uses = filelocList_new ();
3897 e->isPrivate = priv;
3898 e->hasNameError = FALSE;
3900 e->info = (uinfo) dmalloc (sizeof (*e->info));
3901 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3902 e->info->datatype->abs = NO;
3903 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3904 e->info->datatype->type = t;
3905 e->warn = warnClause_undefined; /*@i452@*/
3907 if (uentry_isDeclared (e))
3909 uentry_setDefined (e, fl);
3915 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3917 cstring sname = makeStruct (n);
3918 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3920 cstring_free (sname);
3925 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3927 cstring sname = makeStruct (n);
3928 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3930 cstring_free (sname);
3935 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3937 cstring uname = makeUnion (n);
3938 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3940 cstring_free (uname);
3946 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3948 cstring ename = makeEnum (n);
3949 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3951 cstring_free (ename);
3957 uentry_makeUnionTagLoc (cstring n, ctype t)
3959 cstring uname = makeUnion (n);
3960 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3962 cstring_free (uname);
3967 uentry_makeEnumTagLoc (cstring n, ctype t)
3969 cstring ename = makeEnum (n);
3970 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3972 cstring_free (ename);
3977 uentry_isStructTag (uentry ue)
3979 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3983 uentry_isUnionTag (uentry ue)
3985 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
3989 uentry_isEnumTag (uentry ue)
3991 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
3995 uentry_isAnyTag (uentry ue)
3997 return (uentry_isStructTag (ue)
3998 || uentry_isUnionTag (ue)
3999 || uentry_isEnumTag (ue));
4002 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4004 extern void uentry_destroyMod (void)
4005 /*@globals killed emarker@*/ /*@modifies emarker@*/
4007 static bool wasDestroyed = FALSE;
4009 llassert (!wasDestroyed);
4011 if (emarker != NULL)
4013 uentry_reallyFree (emarker);
4016 wasDestroyed = TRUE;
4020 uentry_makeElipsisMarker (void)
4022 if (emarker == NULL)
4024 emarker = uentry_alloc ();
4026 emarker->ukind = KELIPSMARKER;
4027 emarker->uname = cstring_makeLiteral ("...");
4028 emarker->utype = ctype_elipsMarker;
4029 emarker->sref = sRef_undefined;
4030 emarker->storageclass = SCNONE;
4031 emarker->used = FALSE;
4032 emarker->lset = FALSE;
4033 emarker->info = NULL;
4035 uentry_setSpecDef (emarker, fileloc_undefined);
4036 emarker->uses = filelocList_new ();
4037 emarker->isPrivate = FALSE;
4038 emarker->hasNameError = FALSE;
4041 /*@ignore@*/ return (emarker); /*@end@*/
4049 uentry_equiv (uentry p1, uentry p2)
4051 if (uentry_compare (p1, p2) != 0)
4062 uentry_xcomparealpha (uentry *p1, uentry *p2)
4066 if ((res = uentry_compare (*p1, *p2)) == 0) {
4067 if ((*p1 != NULL) && (*p2 != NULL)) {
4068 res = cstring_compare ((*p1)->uname,
4077 uentry_xcompareuses (uentry *p1, uentry *p2)
4082 if (uentry_isValid (u1))
4084 if (uentry_isValid (u2))
4086 return (-1 * int_compare (filelocList_size (u1->uses),
4087 filelocList_size (u2->uses)));
4096 if (uentry_isValid (u2))
4108 uentry_compareStrict (uentry v1, uentry v2)
4110 COMPARERETURN (uentry_compare (v1, v2));
4112 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4114 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4115 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4116 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4123 uentry_compare (uentry u1, uentry u2)
4125 if (u1 == u2) return 0;
4127 if (uentry_isInvalid (u1)) return -1;
4128 if (uentry_isInvalid (u2)) return 1;
4130 INTCOMPARERETURN (u1->ukind, u2->ukind);
4131 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4132 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4133 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4139 /* bug detected by lclint:
4140 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4145 return (multiVal_compare (uentry_getConstantValue (u1),
4146 uentry_getConstantValue (u2)));
4150 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4152 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4153 uentry_accessType (u2)));
4154 return (uentryList_compareParams (uentry_getParams (u1),
4155 uentry_getParams (u2)));
4157 return (typeIdSet_compare (uentry_accessType (u1),
4158 uentry_accessType (u2)));
4161 ** Functions are never equivalent
4164 if ((int) u1 < (int) u2)
4174 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4175 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4176 sRef_getOrigAliasKind (u2->sref)));
4177 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4178 sRef_getOrigExKind (u2->sref)));
4179 COMPARERETURN (generic_compare (u1->info->var->checked,
4180 u2->info->var->checked));
4181 COMPARERETURN (generic_compare (u1->info->var->defstate,
4182 u2->info->var->defstate));
4183 return (generic_compare (u1->info->var->nullstate,
4184 u2->info->var->nullstate));
4186 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4187 u2->info->datatype->type));
4188 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4189 u2->info->datatype->mut));
4190 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4199 ** all entries are: <type>[@<info>]*#<name>
4201 ** info depends on kind:
4205 advanceField (char **s)
4207 reader_checkChar (s, '@');
4211 advanceName (char **s)
4213 reader_checkChar (s, '#');
4217 vkind_fromInt (int i)
4219 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4221 llbuglit ("vkind_fromInt: out of range");
4228 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4229 typeIdSet access, nstate nullstate,
4230 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4232 uentry e = uentry_alloc ();
4237 e->sref = sRef_makeConst (ct);
4239 sRef_setNullState (e->sref, nullstate, loc);
4240 e->storageclass = SCNONE;
4242 if (fileloc_isSpec (loc))
4244 e->whereSpecified = loc;
4245 e->whereDeclared = fileloc_undefined;
4249 e->whereSpecified = fileloc_undefined;
4250 e->whereDeclared = loc;
4253 e->whereDefined = fileloc_undefined;
4254 e->uses = filelocList_new ();
4255 e->isPrivate = FALSE;
4256 e->hasNameError = FALSE;
4261 e->warn = warnClause_undefined; /*@i452@*/
4263 e->info = (uinfo) dmalloc (sizeof (*e->info));
4264 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4265 e->info->uconst->access = access;
4267 uentry_setConstantValue (e, m);
4268 sRef_storeState (e->sref);
4273 static /*@only@*/ uentry
4274 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4275 sstate defstate, nstate isnull, alkind aliased,
4276 exkind exp, chkind checked,
4277 /*@only@*/ fileloc loc)
4279 uentry e = uentry_alloc ();
4284 e->storageclass = SCNONE;
4286 e->sref = sRef_makeType (ct);
4287 sRef_setNullState (e->sref, isnull, loc);
4289 e->whereDefined = fileloc_undefined;
4291 if (fileloc_isSpec (loc))
4293 e->whereSpecified = loc;
4294 e->whereDeclared = fileloc_undefined;
4298 e->whereSpecified = fileloc_undefined;
4299 e->whereDeclared = loc;
4302 e->isPrivate = FALSE;
4303 e->hasNameError = FALSE;
4308 e->uses = filelocList_new ();
4309 e->warn = warnClause_undefined; /*@i452@*/
4311 e->info = (uinfo) dmalloc (sizeof (*e->info));
4312 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4313 e->info->var->kind = kind;
4314 e->info->var->checked = checked;
4315 e->info->var->defstate = defstate;
4317 sRef_setDefState (e->sref, defstate, loc);
4319 e->info->var->nullstate = sRef_getNullState (e->sref);
4321 sRef_setExKind (e->sref, exp, loc);
4322 sRef_setAliasKind (e->sref, aliased, loc);
4324 sRef_storeState (e->sref);
4326 /*DRL ADDED 9-1-2000 */
4327 e->info->var->bufinfo = NULL;
4332 static /*@only@*/ uentry
4333 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4334 ynm mut, ctype rtype, alkind ak, exkind exp,
4335 sstate defstate, nstate isnull,
4336 /*@only@*/ fileloc loc)
4338 uentry e = uentry_alloc ();
4340 e->ukind = KDATATYPE;
4341 /* e->shallowCopy = FALSE; */
4344 e->storageclass = SCNONE;
4345 e->sref = sRef_makeUnknown ();
4346 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4349 ** This is only setting null state. (I think?)
4352 if (ctype_isUA (ct))
4354 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4356 if (uentry_isValid (te))
4358 sRef_setStateFromUentry (e->sref, te);
4362 /* problem for recursive type definitions */
4366 sRef_setAliasKind (e->sref, ak, loc);
4367 sRef_setExKind (e->sref, exp, loc);
4369 sRef_setDefState (e->sref, defstate, loc);
4371 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4373 isnull = NS_ABSNULL;
4376 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4377 sRef_mergeNullState (e->sref, isnull);
4379 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4381 if (fileloc_isSpec (loc))
4383 e->whereSpecified = loc;
4384 e->whereDeclared = fileloc_undefined;
4388 e->whereSpecified = fileloc_undefined;
4389 e->whereDeclared = loc;
4392 e->isPrivate = FALSE;
4393 e->hasNameError = FALSE;
4395 e->warn = warnClause_undefined; /*@i452@*/
4399 e->uses = filelocList_new ();
4401 e->info = (uinfo) dmalloc (sizeof (*e->info));
4402 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4403 e->info->datatype->abs = abstract;
4404 e->info->datatype->mut = mut;
4405 e->info->datatype->type = rtype;
4407 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4408 sRef_storeState (e->sref);
4409 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4415 static void uentry_setHasGlobs (uentry ue)
4417 llassert (uentry_isFunction (ue));
4419 ue->info->fcn->hasGlobs = TRUE;
4422 static void uentry_setHasMods (uentry ue)
4424 llassert (uentry_isFunction (ue));
4426 ue->info->fcn->hasMods = TRUE;
4430 bool uentry_hasGlobs (uentry ue)
4432 if (uentry_isFunction (ue))
4434 return (ue->info->fcn->hasGlobs);
4440 bool uentry_hasStateClauseList (uentry ue)
4442 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4445 bool uentry_hasConditions (uentry ue)
4447 return (uentry_isFunction (ue)
4448 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4449 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4452 stateClauseList uentry_getStateClauseList (uentry ue)
4454 if (!uentry_isFunction (ue))
4456 llassert (uentry_isFunction (ue));
4457 return stateClauseList_undefined;
4460 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4461 return ue->info->fcn->specclauses;
4464 bool uentry_hasMods (uentry ue)
4466 if (uentry_isFunction (ue))
4468 return (ue->info->fcn->hasMods);
4475 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4477 bool hasGlobs, /*@only@*/ globSet globs,
4478 bool hasMods, /*@only@*/ sRefSet mods,
4479 alkind ak, exkind exp,
4480 sstate defstate, nstate isnull,
4484 /*@only@*/ stateClauseList specclauses,
4485 /*@only@*/ warnClause warnclause,
4486 /*@only@*/ fileloc loc)
4488 uentry e = uentry_alloc ();
4491 /* e->shallowCopy = FALSE; */
4495 e->storageclass = SCNONE;
4497 if (ctype_isFunction (ct))
4499 ret = ctype_getReturnType (ct);
4503 if (ctype_isKnown (ct))
4505 llbug (message ("not function: %s", ctype_unparse (ct)));
4508 ret = ctype_unknown;
4511 e->sref = sRef_makeType (ret);
4513 if (ctype_isUA (ret))
4515 sRef_setStateFromType (e->sref, ret);
4518 sRef_setDefined (e->sref, loc);
4519 sRef_setNullState (e->sref, isnull, loc);
4521 sRef_setAliasKind (e->sref, ak, loc);
4522 sRef_setExKind (e->sref, exp, loc);
4523 sRef_setDefState (e->sref, defstate, loc);
4525 e->whereSpecified = loc;
4526 e->whereDefined = fileloc_undefined;
4528 e->isPrivate = FALSE;
4529 e->hasNameError = FALSE;
4533 e->uses = filelocList_new ();
4534 e->warn = warnclause;
4536 e->info = (uinfo) dmalloc (sizeof (*e->info));
4537 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4539 e->info->fcn->exitCode = exitCode;
4540 e->info->fcn->specialCode = sCode;
4541 e->info->fcn->nullPred = nullPred;
4542 e->info->fcn->access = access;
4544 e->info->fcn->specclauses = specclauses;
4545 e->info->fcn->hasGlobs = hasGlobs;
4546 e->info->fcn->globs = globs;
4548 e->info->fcn->hasMods = hasMods;
4549 e->info->fcn->mods = mods;
4551 e->info->fcn->defparams = uentryList_undefined;
4552 e->whereDeclared = fileloc_undefined;
4554 sRef_storeState (e->sref);
4557 e->info->fcn->preconditions = NULL;
4561 e->info->fcn->postconditions = NULL;
4567 static /*@only@*/ uentry
4568 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4569 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4571 uentry e = uentry_alloc ();
4573 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4575 llbuglit ("uentry_makeTagBase: not a tag type");
4578 /* e->shallowCopy = FALSE; */
4582 e->sref = sRef_makeUnknown ();
4583 e->storageclass = SCNONE;
4585 if (fileloc_isSpec (loc))
4587 e->whereSpecified = loc;
4588 e->whereDeclared = fileloc_undefined;
4592 e->whereDeclared = loc;
4593 e->whereSpecified = fileloc_undefined;
4596 e->whereDefined = fileloc_undefined;
4598 e->isPrivate = FALSE;
4599 e->hasNameError = FALSE;
4603 e->uses = filelocList_new ();
4604 e->warn = warnClause_undefined; /*@i452@*/
4606 e->info = (uinfo) dmalloc (sizeof (*e->info));
4607 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4608 e->info->datatype->abs = NO;
4609 e->info->datatype->mut = MAYBE;
4610 e->info->datatype->type = rtype;
4612 sRef_storeState (e->sref);
4618 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4619 ctype ct, /*@only@*/ fileloc loc)
4621 uentry e = uentry_alloc ();
4623 /* e->shallowCopy = FALSE; */
4627 e->sref = sRef_makeUnknown ();
4628 e->storageclass = SCNONE;
4630 if (fileloc_isSpec (loc))
4632 e->whereSpecified = loc;
4633 e->whereDeclared = fileloc_undefined;
4637 e->whereDeclared = loc;
4638 e->whereSpecified = fileloc_undefined;
4641 e->whereDefined = fileloc_undefined;
4643 e->isPrivate = FALSE;
4644 e->hasNameError = FALSE;
4648 e->uses = filelocList_new ();
4649 e->warn = warnClause_undefined; /*@i452@*/
4651 e->info = (uinfo) dmalloc (sizeof (*e->info));
4652 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4653 e->info->iter->access = access;
4654 e->info->iter->mods = sRefSet_undefined;
4655 e->info->iter->globs = globSet_undefined;
4657 sRef_storeState (e->sref);
4662 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4663 /*@only@*/ fileloc loc)
4665 uentry e = uentry_alloc ();
4667 /* e->shallowCopy = FALSE; */
4668 e->ukind = KENDITER;
4669 e->storageclass = SCNONE;
4671 e->utype = ctype_unknown;
4672 e->sref = sRef_makeUnknown ();
4674 if (fileloc_isSpec (loc))
4676 e->whereSpecified = loc;
4677 e->whereDeclared = fileloc_undefined;
4681 e->whereDeclared = loc;
4682 e->whereSpecified = fileloc_undefined;
4685 e->whereDefined = fileloc_undefined;
4687 e->isPrivate = FALSE;
4688 e->hasNameError = FALSE;
4692 e->uses = filelocList_new ();
4693 e->warn = warnClause_undefined; /*@i452@*/
4695 e->info = (uinfo) dmalloc (sizeof (*e->info));
4696 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4697 e->info->enditer->access = access;
4698 sRef_storeState (e->sref);
4703 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4711 uentry_undump (ekind kind, fileloc loc, char **s)
4715 DPRINTF (("Uentry undump: %s", *s));
4719 reader_checkChar (s, '!');
4720 reader_checkChar (s, '.');
4721 ue = uentry_makeElipsisMarker ();
4725 ctype ct = ctype_undump (s);
4739 reader_checkChar (s, '|');
4741 if (reader_optCheckChar (s, '@'))
4743 tkind = vkind_fromInt (reader_getInt (s));
4744 reader_checkChar (s, '|');
4751 if (reader_optCheckChar (s, '$'))
4753 defstate = SS_UNKNOWN;
4754 isnull = NS_UNKNOWN;
4755 aliased = AK_IMPTEMP;
4757 checked = CH_UNKNOWN;
4759 else if (reader_optCheckChar (s, '&'))
4761 defstate = SS_DEFINED;
4762 isnull = NS_UNKNOWN;
4763 aliased = AK_IMPTEMP;
4765 checked = CH_UNKNOWN;
4767 else if (reader_optCheckChar (s, '^'))
4769 defstate = SS_UNKNOWN;
4770 isnull = NS_UNKNOWN;
4771 aliased = AK_IMPTEMP;
4773 checked = CH_UNKNOWN;
4777 defstate = sstate_fromInt (reader_getInt (s));
4778 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4779 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4781 if (reader_optCheckChar (s, '&'))
4784 checked = CH_UNKNOWN;
4788 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4789 advanceField (s); checked = (chkind) (reader_getInt (s));
4794 name = reader_getStringWord (s);
4796 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4798 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4799 isnull, aliased, exp,
4800 checked, fileloc_copy (loc));
4813 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4814 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4815 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4816 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4817 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4818 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4819 advanceField (s); rtype = ctype_undump (s);
4821 name = reader_getStringWord (s);
4822 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4823 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4824 aliased, exp, defstate, isnull,
4825 fileloc_copy (loc));
4842 stateClauseList specclauses = stateClauseList_undefined;
4843 warnClause warnclause = warnClause_undefined;
4845 if (reader_optCheckChar (s, '$'))
4847 defstate = SS_DEFINED;
4848 isnull = NS_UNKNOWN;
4849 exitCode = XK_UNKNOWN;
4851 nullPred = qual_createUnknown ();
4855 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4856 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4857 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4858 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4859 advanceField (s); nullPred = qual_undump (s);
4862 if (reader_optCheckChar (s, '$'))
4865 globs = globSet_undefined;
4867 mods = sRefSet_undefined;
4869 else if (reader_optCheckChar (s, '^'))
4872 globs = globSet_undefined;
4874 mods = sRefSet_undefined;
4878 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4879 advanceField (s); globs = globSet_undump (s);
4880 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4881 advanceField (s); mods = sRefSet_undump (s);
4884 if (reader_optCheckChar (s, '$'))
4891 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4892 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4895 advanceField (s); access = typeIdSet_undump (s);
4898 ** Optional clauses: Start with @<code>:
4901 while (reader_optCheckChar (s, '@'))
4903 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4905 reader_checkChar (s, ':');
4906 warnclause = warnClause_undump (s);
4908 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4910 reader_checkChar (s, ':');
4911 specclauses = stateClauseList_undump (s);
4919 advanceName (s); name = reader_getStringWord (s);
4921 ue = uentry_makeFunctionBase (name, ct, access,
4924 ak, exp, defstate, isnull,
4925 exitCode, specc, nullPred,
4928 fileloc_copy (loc));
4929 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4936 advanceField (s); access = typeIdSet_undump (s);
4937 advanceName (s); name = reader_getStringWord (s);
4939 ue = uentry_makeIterBase (name, access, ct,
4940 fileloc_copy (loc));
4947 advanceField (s); access = typeIdSet_undump (s);
4948 advanceName (s); name = reader_getStringWord (s);
4950 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4960 if (reader_optCheckChar (s, '$'))
4962 val = multiVal_undefined;
4963 access = typeIdSet_undefined;
4964 nullstate = NS_UNKNOWN;
4968 advanceField (s); val = multiVal_undump (s);
4969 advanceField (s); access = typeIdSet_undump (s);
4970 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4973 advanceName (s); name = reader_getStringWord (s);
4975 ue = uentry_makeConstantBase (name, ct, access,
4976 nullstate, fileloc_copy (loc), val);
4985 advanceField (s); rtype = ctype_undump (s);
4986 advanceName (s); name = reader_getStringWord (s);
4987 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
4991 llcontbuglit ("uentry_undump: invalid");
4992 ue = uentry_undefined;
4995 llcontbuglit ("uentry_undump: elips marker");
4996 ue = uentry_undefined;
5005 uentry_dump (uentry v)
5007 return (uentry_dumpAux (v, FALSE));
5011 uentry_dumpParam (uentry v)
5013 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5014 ("dump: %s", uentry_unparseFull (v)));
5016 return (uentry_dumpAux (v, TRUE));
5020 uentry_dumpAux (uentry v, bool isParam)
5022 llassert (uentry_isValid (v));
5023 llassert (!uentry_isGlobalMarker (v));
5025 DPRINTF (("Dump uentry: [%p]", v));
5026 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5031 llcontbuglit ("uentry_dump: invalid entry");
5032 return cstring_undefined;
5034 return (message ("!."));
5038 vkind vk = v->info->var->kind;
5039 sstate dss = sRef_getDefState (v->sref);
5040 nstate nst = sRef_getNullState (v->sref);
5041 alkind alk = sRef_getAliasKind (v->sref);
5042 exkind exk = sRef_getExKind (v->sref);
5043 chkind chk = v->info->var->checked;
5045 DPRINTF (("Dumping var"));
5047 if (dss == SS_UNKNOWN
5048 && nst == NS_UNKNOWN
5049 && alk == AK_IMPTEMP
5050 && exk == XO_UNKNOWN
5051 && chk == CH_UNKNOWN)
5053 sdump = cstring_makeLiteral ("$");
5055 else if (dss == SS_DEFINED
5056 && nst == NS_UNKNOWN
5057 && alk == AK_IMPTEMP
5058 && exk == XO_UNKNOWN
5059 && chk == CH_UNKNOWN)
5061 sdump = cstring_makeLiteral ("&");
5063 else if (dss == SS_UNKNOWN
5064 && nst == NS_UNKNOWN
5065 && alk == AK_UNKNOWN
5066 && exk == XO_UNKNOWN
5067 && chk == CH_UNKNOWN)
5069 sdump = cstring_makeLiteral ("^");
5071 else if (exk == XO_UNKNOWN
5072 && chk == CH_UNKNOWN)
5074 sdump = message ("%d@%d@%d&",
5081 sdump = message ("%d@%d@%d@%d@%d",
5092 return (message ("%q|@%d|%q#%s",
5093 ctype_dump (v->utype),
5096 isParam ? cstring_undefined : v->uname));
5100 return (message ("%q|%q#%s",
5101 ctype_dump (v->utype),
5103 isParam ? cstring_undefined : v->uname));
5109 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5111 exkind_unparse (sRef_getExKind (v->sref)),
5112 ctype_unparse (v->utype), (int) v->utype));
5115 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5116 ctype_dump (v->utype),
5117 ynm_unparseCode (v->info->datatype->abs),
5118 ynm_unparseCode (v->info->datatype->mut),
5119 (int) sRef_getDefState (v->sref),
5120 (int) sRef_getNullState (v->sref),
5121 (int) sRef_getAliasKind (v->sref),
5122 (int) sRef_getExKind (v->sref),
5123 ctype_dump (v->info->datatype->type),
5127 cstring sdump, gdump, adump, xdump;
5128 alkind alk = sRef_getAliasKind (v->sref);
5129 exkind exk = sRef_getExKind (v->sref);
5131 if (sRef_getDefState (v->sref) == SS_DEFINED
5132 && !nstate_isKnown (sRef_getNullState (v->sref))
5133 && !exitkind_isKnown (v->info->fcn->exitCode)
5134 && v->info->fcn->specialCode == SPC_NONE
5135 && qual_isUnknown (v->info->fcn->nullPred))
5137 sdump = cstring_makeLiteral ("$");
5141 sdump = message ("@%d@%d@%d@%d@%x",
5142 (int) sRef_getDefState (v->sref),
5143 (int) sRef_getNullState (v->sref),
5144 (int) v->info->fcn->exitCode,
5145 (int) v->info->fcn->specialCode,
5146 qual_dump (v->info->fcn->nullPred));
5149 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5151 gdump = cstring_makeLiteral ("$");
5153 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5154 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5156 gdump = cstring_makeLiteral ("^");
5160 gdump = message ("@%s@%q@%s@%q",
5161 bool_dump (uentry_hasGlobs (v)),
5162 globSet_dump (uentry_getGlobs (v)),
5163 bool_dump (uentry_hasMods (v)),
5164 sRefSet_dump (uentry_getMods (v)));
5167 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5169 adump = cstring_makeLiteral ("$");
5173 adump = message ("@%d@%d", (int) alk, (int) exk);
5176 xdump = cstring_undefined;
5178 if (uentry_hasWarning (v))
5180 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5183 if (uentry_hasStateClauseList (v))
5185 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5188 return (message ("%q%q%q%q@%q%q#%s",
5189 ctype_dump (v->utype),
5193 typeIdSet_dump (uentry_accessType (v)),
5198 return (message ("%q@%q#%s",
5199 ctype_dump (v->utype),
5200 typeIdSet_dump (v->info->iter->access),
5203 return (message ("%q@%q#%s",
5204 ctype_dump (v->utype),
5205 typeIdSet_dump (uentry_accessType (v)),
5212 if (multiVal_isUnknown (uentry_getConstantValue (v))
5213 && typeIdSet_isEmpty (uentry_accessType (v))
5214 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5216 sdump = cstring_makeLiteral ("$");
5220 sdump = message ("@%q@%q@%d",
5221 multiVal_dump (uentry_getConstantValue (v)),
5222 typeIdSet_dump (uentry_accessType (v)),
5223 (int) sRef_getNullState (v->sref));
5226 return (message ("%q%q#%s",
5227 ctype_dump (v->utype),
5234 return (message ("%q@%q#%s",
5235 ctype_dump (v->utype),
5236 ctype_dump (v->info->datatype->type), v->uname));
5243 uentry_unparseAbbrev (uentry v)
5245 if (!uentry_isVariable (v))
5247 llcontbuglit ("uentry_unparseAbbrev: not variable");
5248 return uentry_unparse (v);
5251 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5255 uentry_unparse (uentry v)
5259 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5260 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5262 st = uentry_getName (v);
5264 if (cstring_isDefined (st))
5266 return (ctype_unparseDeclaration (v->utype, st));
5271 return (cstring_copy (ctype_unparse (v->utype)));
5276 uentry_unparseFull (uentry v)
5278 if (uentry_isUndefined (v))
5280 return (cstring_makeLiteral ("<undefined>"));
5286 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5287 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5288 ctype_unparse (v->utype),
5289 fileloc_unparse (uentry_whereSpecified (v)),
5290 fileloc_unparse (uentry_whereDeclared (v)),
5291 fileloc_unparse (uentry_whereDefined (v)));
5293 DPRINTF (("uentry: %s", res));
5295 if (uentry_isDatatype (v))
5297 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5300 (ctype_isDefined (v->info->datatype->type)
5301 ? v->info->datatype->type : ctype_unknown),
5302 ynm_unparse (v->info->datatype->mut),
5303 ynm_unparse (v->info->datatype->abs),
5304 sRef_unparseState (v->sref));
5306 else if (uentry_isFunction (v))
5308 res = message ("%q / sref: %q / mods: %q / "
5309 "globs: %q / clauses: %q / pre: %q / post: %q",
5311 sRef_unparseFull (v->sref),
5312 sRefSet_unparse (v->info->fcn->mods),
5313 globSet_unparse (v->info->fcn->globs),
5314 stateClauseList_unparse (v->info->fcn->specclauses),
5315 functionConstraint_unparse (v->info->fcn->preconditions),
5316 functionConstraint_unparse (v->info->fcn->postconditions));
5318 else if (uentry_isIter (v))
5320 res = message ("%q / sref: %q",
5322 sRef_unparseFull (v->sref));
5324 else if (uentry_isVariable (v))
5326 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5328 sRef_unparseFull (v->sref),
5329 (int) v->info->var->kind,
5330 (int) v->info->var->defstate,
5331 (int) v->info->var->nullstate,
5333 DPRINTF (("sref: [%p]", v->sref));
5334 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5335 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5337 else if (uentry_isConstant (v))
5339 res = message ("%q = %q",
5340 res, multiVal_unparse (uentry_getConstantValue (v)));
5344 res = message ("%q :: %q", res, uentry_unparse (v));
5351 bool uentry_hasAccessType (uentry e)
5353 if (uentry_isValid (e))
5358 return (!typeIdSet_isEmpty (e->info->iter->access));
5360 return (!typeIdSet_isEmpty (e->info->enditer->access));
5362 return (!typeIdSet_isEmpty (e->info->fcn->access));
5365 return (!typeIdSet_isEmpty (e->info->uconst->access));
5374 typeIdSet uentry_accessType (uentry e)
5376 if (uentry_isValid (e))
5381 return (e->info->iter->access);
5383 return (e->info->enditer->access);
5385 return (e->info->fcn->access);
5388 return (e->info->uconst->access);
5394 return typeIdSet_undefined;
5398 uentry_isVariable (uentry e)
5400 return (uentry_isVar (e));
5404 uentry_isSpecified (uentry e)
5406 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5410 uentry_isReallySpecified (uentry e)
5412 return (uentry_isValid (e)
5413 && fileloc_isRealSpec (e->whereSpecified));
5417 uentry_isVar (uentry e)
5419 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5423 uentry_isFakeTag (uentry e)
5425 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5429 uentry_isDatatype (uentry e)
5431 return (!uentry_isUndefined (e) &&
5432 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5433 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5437 uentry_setAbstract (uentry e)
5441 llassert (uentry_isDatatype (e)
5442 && (ynm_isMaybe (e->info->datatype->abs)));
5444 oldid = ctype_typeId (e->info->datatype->type);
5445 e->info->datatype->abs = YES;
5446 e->info->datatype->type = ctype_createAbstract (oldid);
5450 uentry_setConcrete (uentry e)
5452 llassert (uentry_isDatatype (e)
5453 && (ynm_isMaybe (e->info->datatype->abs)));
5455 e->info->datatype->abs = NO;
5459 uentry_isAbstractDatatype (uentry e)
5461 return (uentry_isDatatype (e)
5462 && (ynm_isOn (e->info->datatype->abs)));
5466 uentry_isMaybeAbstract (uentry e)
5468 return (uentry_isDatatype (e)
5469 && (ynm_isMaybe (e->info->datatype->abs)));
5473 uentry_isMutableDatatype (uentry e)
5475 bool res = uentry_isDatatype (e)
5476 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5482 uentry_isRefCountedDatatype (uentry e)
5484 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5488 uentry_isParam (uentry u)
5490 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5491 || u->info->var->kind == VKYIELDPARAM));
5495 uentry_isExpandedMacro (uentry u)
5497 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5501 uentry_isSefParam (uentry u)
5503 return (uentry_isVariable (u)
5504 && (u->info->var->kind == VKSEFPARAM
5505 || u->info->var->kind == VKREFSEFPARAM
5506 || u->info->var->kind == VKSEFRETPARAM
5507 || u->info->var->kind == VKREFSEFRETPARAM));
5511 uentry_isRefParam (uentry u)
5513 return (uentry_isVariable (u)
5514 && (u->info->var->kind == VKREFPARAM
5515 || u->info->var->kind == VKREFYIELDPARAM
5516 || u->info->var->kind == VKREFSEFPARAM
5517 || u->info->var->kind == VKREFSEFRETPARAM));
5521 uentry_isAnyParam (uentry u)
5523 return (uentry_isVariable (u)
5524 && ((u->info->var->kind == VKPARAM)
5525 || (u->info->var->kind == VKSEFPARAM)
5526 || (u->info->var->kind == VKYIELDPARAM)
5527 || (u->info->var->kind == VKRETPARAM)
5528 || (u->info->var->kind == VKSEFRETPARAM)));
5532 uentry_getDefState (uentry u)
5534 if (uentry_isValid (u))
5536 return (sRef_getDefState (u->sref));
5540 return (SS_UNKNOWN);
5545 uentry_isOut (uentry u)
5547 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5548 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5552 uentry_isPartial (uentry u)
5554 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5555 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5559 uentry_isStateSpecial (uentry u)
5561 return ((uentry_isVariable (u)
5562 && (u->info->var->defstate == SS_SPECIAL))
5563 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5566 exitkind uentry_getExitCode (uentry ue)
5568 if (uentry_isFunction (ue))
5570 return ue->info->fcn->exitCode;
5578 qual uentry_nullPred (uentry u)
5580 llassert (uentry_isRealFunction (u));
5582 if (uentry_isFunction (u))
5584 return (u->info->fcn->nullPred);
5588 return qual_createUnknown ();
5593 ** Note for variables, this is checking the declared state, not the current state.
5597 uentry_possiblyNull (uentry u)
5599 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5600 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5604 uentry_getAliasKind (uentry u)
5606 if (uentry_isValid (u))
5608 return (sRef_getAliasKind (uentry_getSref (u)));
5617 uentry_getExpKind (uentry u)
5619 if (uentry_isValid (u))
5621 return (sRef_getExKind (uentry_getSref (u)));
5630 uentry_isIter (uentry e)
5632 return (!uentry_isUndefined (e) && e->ukind == KITER);
5636 uentry_isEndIter (uentry e)
5638 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5642 uentry_isRealFunction (uentry e)
5644 return (uentry_isFunction (e) ||
5645 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5649 uentry_hasName (uentry e)
5651 if (uentry_isValid (e))
5653 cstring s = e->uname;
5655 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5656 || uentry_isFakeTag (e)));
5665 ** Returns true for fake tags.
5666 ** This is used for dumping the library
5669 bool uentry_hasRealName (uentry e)
5671 return (uentry_isValid (e)
5672 && cstring_isNonEmpty (e->uname)
5673 && !uentry_isGlobalMarker (e));
5677 /*@observer@*/ globSet
5678 uentry_getGlobs (uentry l)
5680 if (uentry_isInvalid (l))
5682 return globSet_undefined;
5685 if (l->ukind != KFCN)
5687 if (l->ukind != KITER && l->ukind != KENDITER)
5689 if (l->ukind == KVAR)
5691 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5693 ekind_unparse (l->ukind)));
5697 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5699 ekind_unparse (l->ukind)));
5702 return globSet_undefined;
5705 return l->info->fcn->globs;
5708 /*@observer@*/ sRefSet
5709 uentry_getMods (uentry l)
5711 llassert (uentry_isValid (l));
5713 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5715 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5716 return sRefSet_undefined;
5719 return l->info->fcn->mods;
5723 uentry_getKind (uentry e)
5725 llassert (uentry_isValid (e));
5730 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5732 llassert (uentry_isEitherConstant (e));
5733 return (sRef_getValue (e->sref));
5736 /*@observer@*/ uentryList
5737 uentry_getParams (uentry l)
5739 if (uentry_isInvalid (l)) return uentryList_undefined;
5746 ctype ct = l->utype;
5748 if (ctype_isFunction (ct))
5750 return (ctype_argsFunction (ct));
5754 return uentryList_undefined;
5759 ctype ct = l->utype;
5761 llassert (ctype_isFunction (ct));
5762 return (ctype_argsFunction (ct));
5769 /*@observer@*/ cstring
5770 uentry_rawName (uentry e)
5772 if (uentry_isValid (e))
5778 return cstring_undefined;
5783 uentry_getOptName (uentry e)
5785 cstring s = uentry_getName (e);
5787 if (cstring_isDefined (s))
5789 s = cstring_appendChar (s, ' ');
5796 uentry_getName (uentry e)
5798 cstring ret = cstring_undefined;
5800 if (uentry_isValid (e))
5802 if (uentry_isAnyTag (e))
5804 ret = fixTagName (e->uname);
5806 else if (uentry_isAnyParam (e))
5808 ret = cstring_copy (fixParamName (e->uname));
5812 ret = cstring_copy (e->uname);
5819 cstring uentry_observeRealName (uentry e)
5821 cstring ret = cstring_undefined;
5823 if (uentry_isValid (e))
5825 if (uentry_isAnyTag (e))
5827 if (isFakeTag (e->uname))
5829 ret = cstring_undefined;
5833 ret = plainTagName (e->uname);
5836 else if (uentry_isAnyParam (e))
5838 ret = fixParamName (e->uname);
5849 cstring uentry_getRealName (uentry e)
5851 if (uentry_isValid (e))
5853 if (uentry_isAnyTag (e))
5855 return (cstring_undefined);
5862 return cstring_undefined;
5865 ctype uentry_getType (uentry e)
5867 if (uentry_isValid (e))
5873 return ctype_unknown;
5877 fileloc uentry_whereLast (uentry e)
5881 if (uentry_isInvalid (e))
5883 return fileloc_undefined;
5886 loc = e->whereDefined;
5888 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5893 loc = uentry_whereDeclared (e);
5895 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5900 loc = uentry_whereSpecified (e);
5904 fileloc uentry_whereEither (uentry e)
5906 if (uentry_isInvalid (e)) return fileloc_undefined;
5908 if (fileloc_isDefined (e->whereDefined)
5909 && !fileloc_isExternal (e->whereDefined))
5911 return e->whereDefined;
5913 else if (fileloc_isDefined (e->whereDeclared))
5915 return e->whereDeclared;
5919 return e->whereSpecified;
5923 fileloc uentry_whereSpecified (uentry e)
5925 if (uentry_isInvalid (e)) return fileloc_undefined;
5927 return (e->whereSpecified);
5930 fileloc uentry_whereDefined (uentry e)
5932 if (uentry_isInvalid (e)) return fileloc_undefined;
5934 return (e->whereDefined);
5937 fileloc uentry_whereDeclared (uentry e)
5939 if (uentry_isInvalid (e)) return fileloc_undefined;
5941 return (e->whereDeclared);
5944 /*@observer@*/ fileloc
5945 uentry_whereEarliest (uentry e)
5947 if (uentry_isInvalid (e)) return fileloc_undefined;
5949 if (fileloc_isDefined (e->whereSpecified))
5951 return (e->whereSpecified);
5953 else if (fileloc_isDefined (e->whereDeclared))
5955 return (e->whereDeclared);
5959 return e->whereDefined;
5964 uentry_setFunctionDefined (uentry e, fileloc loc)
5966 if (uentry_isValid (e))
5968 llassert (uentry_isFunction (e));
5970 if (fileloc_isUndefined (e->whereDeclared))
5972 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5975 if (!fileloc_isDefined (e->whereDefined))
5977 e->whereDefined = fileloc_update (e->whereDefined, loc);
5983 uentry_setDeclDef (uentry e, fileloc f)
5985 uentry_setDeclared (e, f);
5987 if (!uentry_isFunction (e)
5988 && !(uentry_isVariable (e) && uentry_isExtern (e)))
5990 uentry_setDefined (e, f);
5995 uentry_setDeclaredForce (uentry e, fileloc f)
5997 llassert (uentry_isValid (e));
5998 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6002 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6004 llassert (uentry_isValid (e));
6005 fileloc_free (e->whereDeclared);
6006 e->whereDeclared = f;
6010 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6014 llassert (uentry_isValid (e));
6015 oldloc = e->whereDeclared;
6017 if (fileloc_isDefined (oldloc))
6019 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6021 e->whereDeclared = f;
6022 fileloc_free (oldloc);
6031 e->whereDeclared = f;
6032 fileloc_free (oldloc);
6037 uentry_setDeclared (uentry e, fileloc f)
6041 llassert (uentry_isValid (e));
6042 oldloc = e->whereDeclared;
6044 if (fileloc_isDefined (oldloc))
6046 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6048 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6057 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6062 uentry_clearDefined (uentry e)
6064 if (uentry_isValid (e))
6066 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6071 uentry_setDefined (uentry e, fileloc f)
6075 llassert (uentry_isValid (e));
6076 oldloc = e->whereDefined;
6078 if (fileloc_isDefined (oldloc))
6080 if (fileloc_isLib (oldloc)
6081 || fileloc_isImport (oldloc)
6082 || fileloc_isBuiltin (oldloc)
6083 || fileloc_isPreproc (oldloc))
6085 e->whereDefined = fileloc_update (e->whereDefined, f);
6089 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6095 if (optgenerror (FLG_REDEF,
6096 message ("%s %q redefined",
6097 ekind_capName (e->ukind),
6098 uentry_getName (e)),
6101 llgenindentmsg (message ("Previous definition of %q",
6102 uentry_getName (e)),
6110 e->whereDefined = fileloc_update (e->whereDefined, f);
6115 uentry_isCodeDefined (uentry e)
6117 llassert (uentry_isValid (e));
6119 return (fileloc_isDefined (e->whereDefined));
6123 uentry_isDeclared (uentry e)
6125 if (uentry_isValid (e))
6127 return (fileloc_isDefined (e->whereDeclared));
6133 sRef uentry_getSref (uentry e)
6135 /* not true, used for functions too (but shouldn't be? */
6136 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6138 if (uentry_isInvalid (e)) return sRef_undefined;
6143 sRef uentry_getOrigSref (uentry e)
6145 if (uentry_isValid (e))
6147 sRef sr = sRef_copy (uentry_getSref (e));
6149 sRef_resetState (sr);
6150 sRef_clearDerived (sr);
6152 if (uentry_isVariable (e))
6154 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6155 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6162 return sRef_undefined;
6167 ** requires: uentry e is not in a hashed symbol table
6171 uentry_setName (uentry e, /*@only@*/ cstring n)
6173 llassert (uentry_isValid (e));
6175 cstring_free (e->uname);
6180 uentry_setType (uentry e, ctype t)
6182 if (uentry_isValid (e))
6185 sRef_setType (e->sref, t);
6190 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6193 ctype rettype = ctype_unknown;
6195 llassert (uentry_isValid (ue));
6197 uentry_convertVarFunction (ue);
6198 llassert (uentry_isFunction (ue));
6200 rct = ctype_realType (ue->utype);
6202 if (ctype_isFunction (rct))
6204 rettype = ctype_getReturnType (rct);
6207 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6211 uentry_setRefParam (uentry e)
6213 if (!uentry_isVar (e))
6215 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6219 if (e->info->var->kind == VKSEFPARAM)
6221 e->info->var->kind = VKREFSEFPARAM;
6223 else if (e->info->var->kind == VKSEFRETPARAM)
6225 e->info->var->kind = VKREFSEFRETPARAM;
6227 else if (e->info->var->kind == VKYIELDPARAM)
6229 e->info->var->kind = VKREFYIELDPARAM;
6233 e->info->var->kind = VKREFPARAM;
6239 uentry_setParam (uentry e)
6241 if (!uentry_isVar (e))
6243 if (uentry_isElipsisMarker (e))
6249 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6256 if (e->info->var->kind == VKYIELDPARAM
6257 || e->info->var->kind == VKSEFPARAM
6258 || e->info->var->kind == VKSEFRETPARAM)
6264 e->info->var->kind = VKPARAM;
6268 e->uname = makeParam (e->uname);
6269 cstring_free (oldname);
6274 uentry_setSref (uentry e, sRef s)
6276 if (uentry_isValid (e))
6278 if (sRef_isValid (e->sref))
6280 sRef_mergeStateQuietReverse (e->sref, s);
6284 e->sref = sRef_saveCopy (s);
6290 uentry_getAbstractType (uentry e)
6292 llassert (uentry_isDatatype (e));
6295 ** This assertion removed.
6296 ** Okay to have undefined type, for system types
6298 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6299 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6304 if (ctype_isUndefined (e->info->datatype->type))
6306 return ctype_unknown;
6310 ** Sadly, a kludge...
6313 if (ctype_isUserBool (e->info->datatype->type)) {
6317 return e->info->datatype->type;
6320 ctype uentry_getRealType (uentry e)
6323 typeId uid = USYMIDINVALID;
6325 if (uentry_isInvalid (e))
6327 return ctype_unknown;
6330 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6332 if (uentry_isAnyTag (e))
6337 if (uentry_isAbstractType (e))
6339 ct = uentry_getAbstractType (e);
6341 if (ctype_isManifestBool (ct)) {
6345 llassert (ctype_isUA (ct));
6347 uid = ctype_typeId (ct);
6349 if (!context_hasAccess (uid))
6355 ct = uentry_getType (e);
6357 /* if (ctype_isUserBool (ct)) return ct; */
6359 if (ctype_isManifestBool (ct)) {
6363 if (ctype_isUA (ct))
6365 usymId iid = ctype_typeId (ct);
6367 if (usymId_equal (iid, uid))
6369 llcontbug (message ("uentry_getRealType: recursive type! %s",
6370 ctype_unparse (ct)));
6375 /* evs 2000-07-25: possible infinite recursion ? */
6376 uentry ue2 = usymtab_getTypeEntry (iid);
6380 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6381 return ctype_unknown;
6384 return uentry_getRealType (ue2);
6393 ctype uentry_getForceRealType (uentry e)
6396 typeId uid = USYMIDINVALID;
6398 if (uentry_isInvalid (e))
6400 return ctype_unknown;
6403 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6405 if (uentry_isAnyTag (e))
6410 if (uentry_isAbstractType (e))
6412 ct = uentry_getAbstractType (e);
6413 llassert (ctype_isUA (ct));
6415 uid = ctype_typeId (ct);
6416 /* no check for access! */
6419 ct = uentry_getType (e);
6421 /* evs 2000-07-25 */
6422 /* if (ctype_isUserBool (ct)) return ct; */
6424 if (ctype_isManifestBool (ct)) {
6428 if (ctype_isUA (ct))
6430 usymId iid = ctype_typeId (ct);
6432 if (usymId_equal (iid, uid))
6434 llcontbug (message ("uentry_getRealType: recursive type! %s",
6435 ctype_unparse (ct)));
6440 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6449 uentry uentry_nameCopy (cstring name, uentry e)
6451 uentry enew = uentry_alloc ();
6453 llassert (uentry_isValid (e));
6455 /* enew->shallowCopy = FALSE; */
6456 enew->ukind = e->ukind;
6458 enew->utype = e->utype;
6459 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6460 enew->whereDefined = fileloc_copy (e->whereDefined);
6461 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6462 enew->sref = sRef_copy (e->sref);
6463 enew->used = e->used;
6465 enew->isPrivate = e->isPrivate;
6466 enew->hasNameError = FALSE;
6468 enew->uses = filelocList_new ();
6469 enew->warn = warnClause_undefined;
6471 enew->storageclass = e->storageclass;
6472 enew->info = uinfo_copy (e->info, e->ukind);
6478 uentry_setDatatype (uentry e, usymId uid)
6480 llassert (uentry_isDatatype (e));
6482 if (uentry_isAbstractType (e))
6484 e->info->datatype->type = ctype_createAbstract (uid);
6488 e->info->datatype->type = ctype_createUser (uid);
6493 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6494 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6497 llassert (uentry_isValid (e));
6499 if (fileloc_isSpec (f) || fileloc_isImport (f))
6501 e->whereSpecified = f;
6502 e->whereDeclared = fileloc_undefined;
6503 e->whereDefined = fileloc_undefined;
6507 e->whereSpecified = fileloc_undefined;
6508 e->whereDeclared = f;
6509 e->whereDefined = fileloc_undefined;
6512 llassert (fileloc_storable (f));
6516 ucinfo_free (/*@only@*/ ucinfo u)
6522 uvinfo_free (/*@only@*/ uvinfo u)
6524 /*drl7x added 6/29/01 */
6525 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6530 udinfo_free (/*@only@*/ udinfo u)
6536 ufinfo_free (/*@only@*/ ufinfo u)
6538 globSet_free (u->globs);
6539 sRefSet_free (u->mods);
6540 stateClauseList_free (u->specclauses);
6545 uiinfo_free (/*@only@*/ uiinfo u)
6551 ueinfo_free (/*@only@*/ ueinfo u)
6556 static /*@only@*/ ucinfo
6557 ucinfo_copy (ucinfo u)
6559 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6560 ret->access = u->access;
6564 static /*@only@*/ uvinfo
6565 uvinfo_copy (uvinfo u)
6567 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6569 ret->kind = u->kind;
6570 ret->nullstate = u->nullstate;
6571 ret->defstate = u->defstate;
6572 ret->checked = u->checked;
6574 /* drl added 07-02-001 */
6575 /* copy null terminated information */
6577 if (u->bufinfo != NULL)
6579 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6580 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6581 ret->bufinfo->size = u->bufinfo->size;
6582 ret->bufinfo->len = u->bufinfo->len;
6587 ret->bufinfo = NULL;
6593 static /*@only@*/ udinfo
6594 udinfo_copy (udinfo u)
6596 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6600 ret->type = u->type;
6605 static /*@only@*/ ufinfo
6606 ufinfo_copy (ufinfo u)
6608 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6610 ret->hasGlobs = u->hasGlobs;
6611 ret->hasMods = u->hasMods;
6612 ret->exitCode = u->exitCode;
6613 ret->specialCode = u->specialCode;
6614 ret->nullPred = u->nullPred;
6615 ret->access = u->access;
6616 ret->globs = globSet_newCopy (u->globs);
6617 ret->mods = sRefSet_newCopy (u->mods);
6618 ret->defparams = u->defparams;
6619 ret->specclauses = stateClauseList_copy (u->specclauses);
6621 ret->preconditions = functionConstraint_copy (u->preconditions);
6622 ret->postconditions = functionConstraint_copy (u->postconditions);
6627 static /*@only@*/ uiinfo
6628 uiinfo_copy (uiinfo u)
6630 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6632 ret->access = u->access;
6633 ret->globs = globSet_newCopy (u->globs);
6634 ret->mods = sRefSet_newCopy (u->mods);
6639 static /*@only@*/ ueinfo
6640 ueinfo_copy (ueinfo u)
6642 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6644 ret->access = u->access;
6649 uinfo_free (uinfo u, ekind kind)
6654 case KCONST: ucinfo_free (u->uconst); break;
6655 case KVAR: uvinfo_free (u->var); break;
6659 case KDATATYPE: udinfo_free (u->datatype); break;
6660 case KFCN: ufinfo_free (u->fcn); break;
6661 case KITER: uiinfo_free (u->iter); break;
6662 case KENDITER: ueinfo_free (u->enditer); break;
6663 case KELIPSMARKER: break;
6664 case KINVALID: break;
6670 static /*@only@*/ /*@null@*/ uinfo
6671 uinfo_copy (uinfo u, ekind kind)
6673 if (kind == KELIPSMARKER || kind == KINVALID)
6679 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6684 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6685 case KVAR: ret->var = uvinfo_copy (u->var); break;
6689 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6690 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6691 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6692 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6700 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6702 filelocList_free (e->uses);
6703 cstring_free (e->uname);
6705 uinfo_free (e->info, e->ukind);
6707 fileloc_free (e->whereSpecified);
6708 fileloc_free (e->whereDefined);
6709 fileloc_free (e->whereDeclared);
6711 warnClause_free (e->warn);
6717 extern void uentry_markOwned (/*@owned@*/ uentry u)
6719 sfreeEventually (u);
6723 uentry_free (/*@only@*/ uentry e)
6725 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6727 uentry_reallyFree (e);
6732 ** For uentry's in the global or file scope
6736 uentry_freeComplete (/*@only@*/ uentry e)
6738 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6740 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6741 /*@i@*/ sRef_free (e->sref);
6742 e->sref = sRef_undefined;
6743 uentry_reallyFree (e);
6748 ** requires old->kind != new->kind, old->uname = new->uname
6752 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6754 llassert (uentry_isValid (old));
6755 llassert (uentry_isValid (unew));
6757 if (uentry_isEitherConstant (unew)
6758 && (fileloc_isPreproc (uentry_whereDeclared (old))
6759 || ctype_isUnknown (old->utype))
6760 && !uentry_isSpecified (old))
6768 if (!uentry_isDeclared (old))
6770 if (uentry_isSpecified (old))
6772 if (uentry_isSpecified (unew))
6774 llbuglit ("Respecification!");
6776 else if (uentry_isDeclared (unew))
6780 message ("%s %q inconsistently declared as %s: %t",
6781 ekind_capName (old->ukind),
6782 uentry_getName (unew),
6783 ekind_unparseLong (unew->ukind),
6785 uentry_whereDeclared (unew)))
6787 uentry_showWhereLast (old);
6799 message ("%s %q inconsistently declared as %s: %t",
6800 ekind_capName (old->ukind),
6801 uentry_getName (unew),
6802 ekind_unparseLong (unew->ukind),
6804 uentry_whereDeclared (unew)))
6806 uentry_showWhereLast (old);
6812 llassert (uentry_isDeclared (unew));
6816 message ("%s %q inconsistently redeclared as %s",
6817 ekind_capName (old->ukind),
6818 uentry_getName (unew),
6819 ekind_unparseLong (unew->ukind)),
6820 uentry_whereDeclared (unew)))
6822 uentry_showWhereLast (old);
6828 uentry_updateInto (old, unew);
6832 ** def is the definition of spec, modifies spec
6834 ** reports any inconsistencies
6835 ** returns the summary of all available information
6836 ** if spec and def are inconsistent, def is returned
6840 uentry_showWhereLast (uentry spec)
6842 if (uentry_isValid (spec))
6844 if (fileloc_isDefined (spec->whereDefined)
6845 && !fileloc_isLib (spec->whereDefined)
6846 && !fileloc_isPreproc (spec->whereDefined))
6848 llgenindentmsg (message ("Previous definition of %q: %t",
6849 uentry_getName (spec),
6850 uentry_getType (spec)),
6851 uentry_whereDefined (spec));
6853 else if (uentry_isDeclared (spec))
6855 llgenindentmsg (message ("Previous declaration of %q: %t",
6856 uentry_getName (spec),
6857 uentry_getType (spec)),
6858 uentry_whereDeclared (spec));
6860 else if (uentry_isSpecified (spec))
6862 if (uentry_hasName (spec))
6864 llgenindentmsg (message ("Specification of %q: %t",
6865 uentry_getName (spec),
6866 uentry_getType (spec)),
6867 uentry_whereSpecified (spec));
6871 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6872 uentry_whereSpecified (spec));
6877 /* nothing to show */
6883 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6885 fileloc loc = uentry_whereDefined (ce);
6887 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6889 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6893 loc = uentry_whereSpecified (ce);
6895 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6897 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6902 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6904 if (uentry_isDeclared (spec))
6906 llgenindentmsg (message ("Previous declaration of %q: %q",
6907 uentry_getName (spec), extra),
6908 uentry_whereDeclared (spec));
6910 else if (uentry_isSpecified (spec))
6912 llgenindentmsg (message ("Specification of %q: %q",
6913 uentry_getName (spec), extra),
6914 uentry_whereSpecified (spec));
6918 cstring_free (extra);
6923 uentry_showWhereDeclared (uentry spec)
6925 if (uentry_isDeclared (spec))
6927 if (uentry_hasName (spec))
6929 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6930 uentry_whereDeclared (spec));
6934 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6937 else if (uentry_isSpecified (spec))
6939 if (uentry_hasName (spec))
6941 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6942 uentry_whereSpecified (spec));
6946 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6951 /* nothing to show */
6957 uentry_showWhereAny (uentry spec)
6959 if (uentry_isDeclared (spec))
6961 if (uentry_hasName (spec))
6963 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6964 uentry_whereDeclared (spec));
6968 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6971 else if (uentry_isSpecified (spec))
6973 if (uentry_hasName (spec))
6975 llgenindentmsg (message ("Specification of %q",
6976 uentry_getName (spec)),
6977 uentry_whereSpecified (spec));
6981 llgenindentmsg (cstring_makeLiteral ("Specification"),
6982 uentry_whereSpecified (spec));
6985 else if (fileloc_isDefined (uentry_whereDefined (spec)))
6987 if (uentry_hasName (spec))
6989 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
6990 uentry_whereDefined (spec));
6994 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
6999 /* nothing to show */
7004 uentry_showWhereDefined (uentry spec)
7006 if (uentry_isCodeDefined (spec))
7008 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7009 uentry_whereDefined (spec));
7014 uentry_showWhereLastPlain (uentry spec)
7016 if (uentry_isDeclared (spec))
7018 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7019 uentry_whereDeclared (spec));
7021 else if (uentry_isSpecified (spec))
7023 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7024 uentry_whereSpecified (spec));
7032 uentry_showWhereLastVal (uentry spec, cstring val)
7034 if (uentry_isDeclared (spec))
7036 llgenindentmsg (message ("Previous declaration of %q: %s",
7037 uentry_getName (spec), val),
7038 uentry_whereDeclared (spec));
7040 else if (uentry_isSpecified (spec))
7042 llgenindentmsg (message ("Specification of %q: %s",
7043 uentry_getName (spec), val),
7044 uentry_whereSpecified (spec));
7052 uentry_showWhereSpecified (uentry spec)
7054 if (uentry_isSpecified (spec))
7056 if (uentry_hasName (spec))
7058 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7059 uentry_whereSpecified (spec));
7063 llgenindentmsg (cstring_makeLiteral ("Specification"),
7064 uentry_whereSpecified (spec));
7067 else if (uentry_isDeclared (spec))
7069 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7070 uentry_whereDeclared (spec));
7074 /* nothing to show */
7079 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7081 if (uentry_isSpecified (spec))
7083 if (uentry_hasName (spec))
7085 llgenindentmsg (message ("Specification of %q: %q",
7086 uentry_getName (spec), s),
7087 uentry_whereSpecified (spec));
7091 llgenindentmsg (message ("Specification: %q", s),
7092 uentry_whereSpecified (spec));
7095 else if (uentry_isDeclared (spec))
7097 llgenindentmsg (message ("Declaration of %q: %q",
7098 uentry_getName (spec), s),
7099 uentry_whereDeclared (spec));
7103 llgenindentmsg (message ("Previous: %q", s),
7104 uentry_whereLast (spec));
7113 checkStructConformance (uentry old, uentry unew)
7116 uentryList fold, fnew;
7119 ** requires: types of old and new are structs or unions
7122 llassert (uentry_isValid (old));
7123 llassert (uentry_isValid (unew));
7125 oldr = ctype_realType (old->utype);
7126 fold = ctype_getFields (oldr);
7128 newr = ctype_realType (unew->utype);
7129 fnew = ctype_getFields (newr);
7131 if (!uentryList_matchFields (fold, fnew))
7133 if (fileloc_equal (uentry_whereLast (old),
7134 uentry_whereLast (unew)))
7142 message ("%q %q %rdeclared with fields { %q }, %s "
7143 "with fields { %q }",
7144 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7145 uentry_getName (old),
7146 uentry_isDeclared (old),
7147 uentryList_unparseAbbrev (fnew),
7148 uentry_specOrDefName (old),
7149 uentryList_unparseAbbrev (fold)),
7150 uentry_whereDeclared (unew)))
7152 uentry_showWhereLastPlain (old);
7153 uentryList_showFieldDifference (fold, fnew);
7157 old->utype = unew->utype;
7162 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7165 ** requires old and new are enums
7168 ctype rold = ctype_realType (old->utype);
7169 ctype rnew = ctype_realType (unew->utype);
7170 enumNameList eold = ctype_elist (rold);
7171 enumNameList enew = ctype_elist (rnew);
7173 if (!enumNameList_match (eold, enew))
7177 message ("Enum %q declared with members { %q } but "
7178 "specified with members { %q }",
7179 uentry_getName (old),
7180 enumNameList_unparse (enew),
7181 enumNameList_unparse (eold)),
7182 uentry_whereDeclared (unew)))
7184 uentry_showWhereSpecified (old);
7185 old->utype = unew->utype;
7191 ** either oldCurrent or newCurrent may be undefined!
7195 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7196 uentry unew, uentry newCurrent, ctype newType,
7199 bool hasError = FALSE;
7201 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7203 if (uentry_hasName (newCurrent))
7205 hasError = optgenerror
7207 message ("Parameter %d, %q, of function %q has inconsistent type: "
7208 "declared %t, %s %t",
7209 paramno + 1, uentry_getName (newCurrent),
7210 uentry_getName (unew),
7211 newType, uentry_specOrDefName (old), oldType),
7212 uentry_whereDeclared (newCurrent));
7216 hasError = optgenerror
7218 message ("Parameter %d of function %q has inconsistent type: "
7219 "declared %t, %s %t",
7220 paramno + 1, uentry_getName (unew),
7221 newType, uentry_specOrDefName (old), oldType),
7222 uentry_whereDeclared (newCurrent));
7224 DPRINTF (("type: %s / %s",
7225 ctype_unparse (newType),
7226 ctype_unparse (ctype_realType (newType))));
7231 if (uentry_isDeclared (unew))
7233 hasError = optgenerror
7235 message ("Parameter %d of function %s has inconsistent type: "
7236 "declared %t, %s %t",
7237 paramno + 1, unew->uname,
7238 newType, uentry_specOrDefName (old), oldType),
7239 uentry_whereDeclared (unew));
7243 hasError = optgenerror
7245 message ("Parameter %d of function %s has inconsistent type: "
7246 "declared %t, %s %t",
7247 paramno + 1, unew->uname,
7248 newType, uentry_specOrDefName (old), oldType),
7249 uentry_whereDeclared (unew));
7255 DPRINTF (("Here: %s / %s",
7256 uentry_unparseFull (oldCurrent),
7257 uentry_unparseFull (newCurrent)));
7259 if (!uentry_isUndefined (oldCurrent))
7261 if (!uentry_isUndefined (newCurrent)
7262 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7264 uentry_showWhereLast (oldCurrent);
7268 uentry_showWhereLastPlain (old);
7271 uentry_setType (oldCurrent, newType);
7275 uentry_showWhereLastPlain (old);
7281 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7285 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7287 uentry_isDeclared (old),
7288 uentryList_size (uentry_getParams (unew)),
7289 uentry_specOrDefName (old),
7290 uentryList_size (uentry_getParams (old))),
7291 uentry_whereDeclared (unew)))
7293 uentry_showWhereLastPlain (old);
7298 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7302 message ("Function %s inconsistently %rdeclared to return %t",
7304 uentry_isDeclared (old),
7305 ctype_getReturnType (unew->utype)),
7306 uentry_whereDeclared (unew)))
7308 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7312 static cstring paramStorageName (uentry ue)
7314 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7317 static cstring fcnErrName (uentry ue)
7319 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7322 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7324 if (uentry_isVar (ue))
7326 return (checkedName (ue->info->var->checked));
7330 return (cstring_makeLiteralTemp ("<checked invalid>"));
7334 static cstring checkedName (chkind checked)
7338 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7339 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7340 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7341 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7342 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7348 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7353 if (uentry_isVar (unew))
7355 llassert (uentry_isVar (old));
7357 oldState = old->info->var->nullstate;
7358 newState = unew->info->var->nullstate;
7362 oldState = sRef_getNullState (old->sref);
7363 newState = sRef_getNullState (unew->sref);
7366 if (oldState == NS_ABSNULL)
7368 if (uentry_isVar (old))
7370 old->info->var->nullstate = newState;
7373 sRef_mergeNullState (old->sref, newState);
7375 else if (newState == NS_UNKNOWN)
7377 if (completeConform && newState != oldState
7378 && uentry_isReallySpecified (old))
7382 message ("%s %q specified as %s, but declared without %s qualifier",
7383 ekind_capName (unew->ukind),
7384 uentry_getName (unew),
7385 nstate_unparse (oldState),
7386 nstate_unparse (oldState)),
7387 uentry_whereDeclared (unew)))
7389 uentry_showWhereSpecified (old);
7393 if (uentry_isVar (unew))
7395 unew->info->var->nullstate = oldState;
7398 sRef_mergeNullState (unew->sref, oldState);
7400 else if (newState == NS_POSNULL)
7402 if (oldState == NS_MNOTNULL
7403 && (ctype_isUA (unew->utype)
7404 || (uentry_isFunction (unew)
7405 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7407 if (uentry_isVar (unew))
7409 unew->info->var->nullstate = oldState;
7412 sRef_mergeNullState (unew->sref, oldState);
7416 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7417 || oldState == NS_UNKNOWN)
7424 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7426 uentry_ekindName (unew),
7427 uentry_getName (unew),
7428 uentry_isDeclared (old),
7430 uentry_specOrDefName (old),
7431 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7432 uentry_whereDeclared (unew)))
7434 uentry_showWhereSpecified (old);
7439 if (uentry_isVar (old))
7441 old->info->var->nullstate = newState;
7444 sRef_mergeNullState (old->sref, newState);
7447 else if (newState == NS_MNOTNULL)
7449 if (oldState != NS_MNOTNULL)
7455 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7456 "%s without notnull qualifier",
7457 uentry_ekindName (unew),
7458 uentry_getName (unew),
7459 uentry_isDeclared (old),
7461 uentry_specOrDefName (old)),
7462 uentry_whereDeclared (unew)))
7464 uentry_showWhereSpecified (old);
7468 if (uentry_isVar (old))
7470 old->info->var->nullstate = newState;
7473 sRef_mergeNullState (old->sref, newState);
7478 if (uentry_isVar (unew))
7480 unew->info->var->nullstate = oldState;
7483 sRef_mergeNullState (unew->sref, oldState);
7488 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7489 bool mustConform, bool completeConform)
7495 if (uentry_isVar (old) && uentry_isVar (unew))
7497 oldState = old->info->var->defstate;
7498 newState = unew->info->var->defstate;
7503 oldState = sRef_getDefState (old->sref);
7504 newState = sRef_getDefState (unew->sref);
7507 if (newState != oldState
7508 && newState != SS_UNKNOWN
7509 && newState != SS_DEFINED)
7515 message ("%s %q inconsistently %rdeclared %s %s %s, "
7517 uentry_ekindName (unew),
7518 uentry_getName (unew),
7519 uentry_isDeclared (old),
7521 sstate_unparse (newState),
7522 paramStorageName (unew),
7523 uentry_specOrDefName (old),
7525 sstate_unparse (oldState),
7526 paramStorageName (unew)),
7527 uentry_whereDeclared (unew)))
7529 uentry_showWhereSpecified (old);
7533 if (vars) old->info->var->defstate = newState;
7534 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7539 && (newState != oldState) && (oldState != SS_DEFINED)
7540 && uentry_isReallySpecified (old))
7544 message ("%s %q specified as %s, but declared without %s qualifier",
7545 ekind_capName (unew->ukind),
7546 uentry_getName (unew),
7547 sstate_unparse (oldState),
7548 sstate_unparse (oldState)),
7549 uentry_whereDeclared (unew)))
7551 uentry_showWhereSpecified (old);
7555 if (vars) unew->info->var->defstate = oldState;
7556 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7561 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7562 bool mustConform, bool completeConform)
7567 oldKind = sRef_getAliasKind (old->sref);
7568 newKind = sRef_getAliasKind (unew->sref);
7570 if (alkind_isImplicit (newKind)
7571 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7573 if (completeConform && !alkind_equal (newKind, oldKind)
7574 && uentry_isReallySpecified (old))
7578 message ("%s %q specified as %s, but declared without "
7579 "explicit alias qualifier",
7580 ekind_capName (unew->ukind),
7581 uentry_getName (unew),
7582 alkind_unparse (oldKind)),
7583 uentry_whereDeclared (unew)))
7585 uentry_showWhereSpecified (old);
7590 ** This really shouldn't be necessary, but it is!
7591 ** Function params (?) use new here.
7594 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7598 if (alkind_isKnown (newKind))
7600 if (!alkind_equal (oldKind, newKind))
7602 if (alkind_isKnown (oldKind))
7607 message ("%s %q inconsistently %rdeclared %s %s storage, "
7609 uentry_ekindName (unew),
7610 uentry_getName (unew),
7611 uentry_isDeclared (old),
7613 alkind_unparse (newKind),
7614 uentry_specOrDefName (old),
7615 alkind_unparse (oldKind)),
7616 uentry_whereDeclared (unew)))
7618 uentry_showWhereSpecified (old);
7620 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7621 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7622 sRef_setAliasKind (old->sref, AK_ERROR,
7623 uentry_whereDeclared (unew));
7627 sRef_setAliasKind (old->sref, newKind,
7628 uentry_whereDeclared (unew));
7633 if (!(alkind_isImplicit (newKind)))
7636 !uentry_isFunction (unew) &&
7639 message ("%s %q inconsistently %rdeclared %s %s storage, "
7640 "implicitly %s as temp storage",
7641 uentry_ekindName (unew),
7642 uentry_getName (unew),
7643 uentry_isDeclared (old),
7645 alkind_unparse (newKind),
7646 uentry_specOrDefName (old)),
7647 uentry_whereDeclared (unew)))
7649 uentry_showWhereSpecified (old);
7653 sRef_setAliasKind (old->sref, newKind,
7654 uentry_whereDeclared (unew));
7656 else /* newKind is temp or refcounted */
7663 else /* newKind unknown */
7670 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7671 bool mustConform, bool completeConform)
7676 oldKind = sRef_getExKind (old->sref);
7677 newKind = sRef_getExKind (unew->sref);
7679 if (exkind_isKnown (newKind))
7681 if (oldKind != newKind)
7683 if (exkind_isKnown (oldKind))
7688 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7689 uentry_ekindName (unew),
7690 uentry_getName (unew),
7691 uentry_isDeclared (old),
7693 exkind_unparse (newKind),
7694 uentry_specOrDefName (old),
7695 exkind_unparse (oldKind)),
7696 uentry_whereDeclared (unew)))
7698 uentry_showWhereSpecified (old);
7701 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7708 message ("%s %q inconsistently %rdeclared %s %s, "
7709 "implicitly %s without exposure qualifier",
7710 uentry_ekindName (unew),
7711 uentry_getName (unew),
7712 uentry_isDeclared (old),
7714 exkind_unparse (newKind),
7715 uentry_specOrDefName (old)),
7716 uentry_whereDeclared (unew)))
7718 uentry_showWhereSpecified (old);
7721 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7727 if (completeConform && exkind_isKnown (oldKind)
7728 && uentry_isReallySpecified (old))
7732 message ("%s %q specified as %s, but declared without "
7733 "exposure qualifier",
7734 ekind_capName (unew->ukind),
7735 uentry_getName (unew),
7736 exkind_unparse (oldKind)),
7737 uentry_whereDeclared (unew)))
7739 uentry_showWhereSpecified (old);
7743 /* yes, this is necessary! (if its a param) */
7744 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7749 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7750 bool mustConform, /*@unused@*/ bool completeConform)
7752 valueTable newvals = sRef_getValueTable (unew->sref);
7754 if (valueTable_isDefined (newvals))
7756 DPRINTF (("Check meta state: %s -> %s",
7757 uentry_unparseFull (old),
7758 uentry_unparseFull (unew)));
7760 DPRINTF (("Check meta state refs: %s -> %s",
7761 sRef_unparseFull (old->sref),
7762 sRef_unparseFull (unew->sref)));
7764 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7767 ** Copy the new values into the old ref
7770 valueTable_elements (newvals, key, newval)
7772 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7773 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7775 llassert (metaStateInfo_isDefined (msinfo));
7777 if (stateValue_isUndefined (oldval))
7779 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7783 if (stateValue_isError (oldval))
7785 if (!stateValue_isError (newval))
7787 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7791 ; /* No change necessary. */
7796 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7798 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7804 if (!stateValue_isError (newval)
7805 && !stateValue_isImplicit (newval))
7807 if (uentry_hasName (unew)
7808 || !sRef_isParam (uentry_getSref (unew)))
7813 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7814 uentry_ekindName (unew),
7815 uentry_getName (unew),
7816 uentry_isDeclared (old),
7818 stateValue_unparseValue (newval, msinfo),
7819 uentry_specOrDefName (old),
7820 stateValue_unparseValue (oldval, msinfo)),
7821 uentry_whereDeclared (unew)))
7823 uentry_showWhereSpecified (old);
7831 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7832 uentry_ekindName (unew),
7833 sRef_getParam (uentry_getSref (unew)),
7834 uentry_isDeclared (old),
7836 stateValue_unparseValue (newval, msinfo),
7837 uentry_specOrDefName (old),
7838 stateValue_unparseValue (oldval, msinfo)),
7839 uentry_whereDeclared (unew)))
7841 uentry_showWhereSpecified (old);
7847 DPRINTF (("Updating!"));
7848 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7852 DPRINTF (("Values match"));
7856 } end_valueTable_elements ;
7861 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7862 /*@notnull@*/ uentry unew,
7863 bool mustConform, bool completeConform)
7865 checkDefState (old, unew, mustConform, completeConform);
7866 checkNullState (old, unew, mustConform, completeConform);
7867 checkAliasState (old, unew, mustConform, completeConform);
7868 checkExpState (old, unew, mustConform, completeConform);
7869 checkMetaState (old, unew, mustConform, completeConform);
7871 sRef_storeState (old->sref);
7872 sRef_storeState (unew->sref);
7876 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7878 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7883 llassert (uentry_isVar (old));
7884 llassert (uentry_isVar (unew));
7886 if (cstring_isEmpty (old->uname))
7888 cstring_free (old->uname);
7889 old->uname = cstring_copy (unew->uname);
7892 if (unew->info->var->kind == VKRETPARAM
7893 || unew->info->var->kind == VKSEFRETPARAM)
7895 if (old->info->var->kind != VKRETPARAM
7896 && old->info->var->kind != VKSEFRETPARAM)
7900 message ("Parameter %q inconsistently %rdeclared as "
7901 "returned parameter",
7902 uentry_getName (unew),
7903 uentry_isDeclared (old)),
7904 uentry_whereDeclared (unew)))
7906 uentry_showWhereSpecified (old);
7907 old->info->var->kind = unew->info->var->kind;
7913 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7915 if (old->info->var->kind != VKSEFPARAM
7916 && old->info->var->kind != VKSEFRETPARAM)
7920 message ("Parameter %qinconsistently %rdeclared as "
7922 uentry_getOptName (unew),
7923 uentry_isDeclared (old)),
7924 uentry_whereDeclared (unew)))
7926 uentry_showWhereSpecified (old);
7927 old->info->var->kind = unew->info->var->kind;
7932 if (old->info->var->kind == VKSPEC)
7934 old->info->var->kind = unew->info->var->kind;
7938 unew->info->var->kind = old->info->var->kind;
7941 if (unew->info->var->checked != CH_UNKNOWN
7942 && unew->info->var->checked != old->info->var->checked)
7944 if (old->info->var->checked == CH_UNKNOWN
7945 && !fileloc_isUser (uentry_whereLast (old)))
7953 message ("Variable %q inconsistently %rdeclared as "
7954 "%s parameter (was %s)",
7955 uentry_getName (unew),
7956 uentry_isDeclared (old),
7957 checkedName (unew->info->var->checked),
7958 checkedName (old->info->var->checked)),
7959 uentry_whereDeclared (unew)))
7961 uentry_showWhereSpecified (old);
7965 old->info->var->checked = unew->info->var->checked;
7970 && (old->info->var->checked != CH_UNKNOWN)
7971 && uentry_isReallySpecified (old))
7975 message ("%s %q specified as %s, but declared without %s qualifier",
7976 ekind_capName (unew->ukind),
7977 uentry_getName (unew),
7978 checkedName (old->info->var->checked),
7979 checkedName (old->info->var->checked)),
7980 uentry_whereDeclared (unew)))
7982 uentry_showWhereSpecified (old);
7986 unew->info->var->checked = old->info->var->checked;
7989 uentry_checkStateConformance (old, unew, mustConform, completeConform);
7992 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
7994 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
7999 llassert (uentry_isVar (u1));
8000 llassert (uentry_isVar (u2));
8002 if (u1->info->var->kind != u2->info->var->kind) {
8003 if (u1->info->var->kind == VKSEFRETPARAM) {
8004 if (u2->info->var->kind == VKRETPARAM) {
8007 message ("Function types are inconsistent. Parameter %d is "
8008 "sef parameter, but non-sef parameter in "
8009 "assigned function: %s",
8010 paramno, exprNode_unparse (e)),
8012 } else if (u2->info->var->kind == VKSEFPARAM) {
8015 message ("Function types are inconsistent. Parameter %d is "
8016 "returns parameter, but non-returns parameter in "
8017 "assigned function: %s",
8018 paramno, exprNode_unparse (e)),
8023 message ("Function types are inconsistent. Parameter %d is "
8024 "sef returns parameter, but non-sef returns parameter in "
8025 "assigned function: %s",
8026 paramno, exprNode_unparse (e)),
8029 } else if (u1->info->var->kind == VKRETPARAM) {
8032 message ("Function types are inconsistent. Parameter %d is "
8033 "returns parameter, but non-returns parameter in "
8034 "assigned function: %s",
8035 paramno, exprNode_unparse (e)),
8037 } else if (u1->info->var->kind == VKSEFPARAM) {
8040 message ("Function types are inconsistent. Parameter %d is "
8041 "sef parameter, but non-sef parameter in "
8042 "assigned function: %s",
8043 paramno, exprNode_unparse (e)),
8046 if (u2->info->var->kind == VKSEFRETPARAM) {
8049 message ("Function types are inconsistent. Parameter %d is "
8050 "normal parameter, but sef returns parameter in "
8051 "assigned function: %s",
8052 paramno, exprNode_unparse (e)),
8054 } else if (u2->info->var->kind == VKSEFPARAM) {
8057 message ("Function types are inconsistent. Parameter %d is "
8058 "normal parameter, but sef parameter in "
8059 "assigned function: %s",
8060 paramno, exprNode_unparse (e)),
8062 } else if (u2->info->var->kind == VKRETPARAM) {
8065 message ("Function types are inconsistent. Parameter %d is "
8066 "normal parameter, but returns parameter in "
8067 "assigned function: %s",
8068 paramno, exprNode_unparse (e)),
8076 if (u1->info->var->defstate != u2->info->var->defstate)
8080 message ("Function types are inconsistent. Parameter %d is "
8081 "%s, but %s in assigned function: %s",
8083 sstate_unparse (u1->info->var->defstate),
8084 sstate_unparse (u2->info->var->defstate),
8085 exprNode_unparse (e)),
8089 if (u1->info->var->nullstate != u2->info->var->nullstate)
8093 message ("Function types are inconsistent. Parameter %d is "
8094 "%s, but %s in assigned function: %s",
8096 nstate_unparse (u1->info->var->nullstate),
8097 nstate_unparse (u2->info->var->nullstate),
8098 exprNode_unparse (e)),
8102 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8106 message ("Function types are inconsistent. Parameter %d is "
8107 "%s, but %s in assigned function: %s",
8109 alkind_unparse (sRef_getAliasKind (u1->sref)),
8110 alkind_unparse (sRef_getAliasKind (u2->sref)),
8111 exprNode_unparse (e)),
8115 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8119 message ("Function types are inconsistent. Parameter %d is "
8120 "%s, but %s in assigned function: %s",
8122 exkind_unparse (sRef_getExKind (u1->sref)),
8123 exkind_unparse (sRef_getExKind (u2->sref)),
8124 exprNode_unparse (e)),
8130 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8131 /*@notnull@*/ uentry unew,
8132 bool mustConform, /*@unused@*/ bool completeConform)
8134 uentryList oldParams = uentry_getParams (old);
8135 uentryList newParams = uentry_getParams (unew);
8136 ctype newType = unew->utype;
8137 ctype oldType = old->utype;
8138 ctype oldRetType = ctype_unknown;
8139 ctype newRetType = ctype_unknown;
8141 DPRINTF (("Function conform: %s ==> %s",
8142 uentry_unparseFull (old),
8143 uentry_unparseFull (unew)));
8145 if (uentry_isForward (old))
8147 mustConform = FALSE;
8148 uentry_updateInto (old, unew);
8153 ** check return values
8156 if (ctype_isKnown (oldType))
8158 llassert (ctype_isFunction (oldType));
8160 oldRetType = ctype_getReturnType (oldType);
8163 if (ctype_isKnown (newType))
8165 llassert (ctype_isFunction (newType));
8167 newRetType = ctype_getReturnType (newType);
8170 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8171 && !ctype_matchDef (newRetType, oldRetType))
8173 if (mustConform) returnValueError (old, unew);
8177 if (ctype_isConj (newRetType))
8179 if (ctype_isConj (oldRetType))
8181 if (!ctype_sameAltTypes (newRetType, oldRetType))
8185 message ("Function %q inconsistently %rdeclared to "
8186 "return alternate types %s "
8187 "(types match, but alternates are not identical, "
8188 "so checking may not be correct)",
8189 uentry_getName (unew),
8190 uentry_isDeclared (old),
8191 ctype_unparse (newRetType)),
8192 uentry_whereDeclared (unew)))
8194 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8200 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8205 DPRINTF (("Before state: %s",
8206 uentry_unparseFull (old)));
8207 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8208 DPRINTF (("After state: %s",
8209 uentry_unparseFull (old)));
8211 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8213 if (exitkind_isKnown (unew->info->fcn->exitCode))
8217 message ("Function %q inconsistently %rdeclared using %s",
8218 uentry_getName (unew),
8219 uentry_isDeclared (old),
8220 exitkind_unparse (unew->info->fcn->exitCode)),
8221 uentry_whereDeclared (unew)))
8223 uentry_showWhereSpecified (old);
8228 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8232 if (!qual_isUnknown (unew->info->fcn->nullPred))
8234 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8238 message ("Function %q inconsistently %rdeclared using %s",
8239 uentry_getName (unew),
8240 uentry_isDeclared (old),
8241 qual_unparse (unew->info->fcn->nullPred)),
8242 uentry_whereDeclared (unew)))
8244 uentry_showWhereSpecified (old);
8250 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8253 if (unew->info->fcn->specialCode != SPC_NONE)
8255 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8259 message ("Function %q inconsistently %rdeclared using %s",
8260 uentry_getName (unew),
8261 uentry_isDeclared (old),
8262 specCode_unparse (unew->info->fcn->specialCode)),
8263 uentry_whereDeclared (unew)))
8265 uentry_showWhereSpecified (old);
8271 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8278 if (!uentryList_sameObject (oldParams, newParams)
8279 && (!uentryList_isMissingParams (oldParams)))
8281 if (!uentryList_isMissingParams (newParams))
8284 int nparams = uentryList_size (oldParams);
8285 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8287 if (nparams != uentryList_size (newParams))
8289 nargsError (old, unew);
8292 if (uentryList_size (newParams) < nparams)
8294 nparams = uentryList_size (newParams);
8297 while (paramno < nparams)
8299 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8300 uentry newCurrent = uentryList_getN (newParams, paramno);
8301 ctype oldCurrentType = uentry_getType (oldCurrent);
8302 ctype newCurrentType = uentry_getType (newCurrent);
8304 llassert (uentry_isValid (oldCurrent)
8305 && uentry_isValid (newCurrent));
8307 if (!uentry_isElipsisMarker (oldCurrent)
8308 && !uentry_isElipsisMarker (newCurrent))
8310 checkVarConformance (oldCurrent, newCurrent,
8311 mustConform, completeConform);
8316 if (uentry_hasName (oldCurrent)
8317 && uentry_hasName (newCurrent))
8319 cstring oldname = uentry_getName (oldCurrent);
8320 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8322 cstring nname = uentry_getName (newCurrent);
8325 if (cstring_isDefined (pfx)
8326 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
8328 oname = cstring_suffix (oldname, cstring_length (pfx));
8333 /*@-branchstate@*/ } /*@=branchstate@*/
8335 if (cstring_isDefined (pfx)
8336 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
8338 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8343 /*@-branchstate@*/ } /*@=branchstate@*/
8345 if (!cstring_equal (oname, nnamefix))
8348 (FLG_DECLPARAMMATCH,
8349 message ("Definition parameter name %s does not match "
8350 "name of corresponding parameter in "
8353 uentry_whereLast (newCurrent)))
8355 uentry_showWhereLastPlain (oldCurrent);
8359 cstring_free (oldname);
8360 cstring_free (nname);
8364 if (!ctype_match (oldCurrentType, newCurrentType))
8366 paramTypeError (old, oldCurrent, oldCurrentType,
8367 unew, newCurrent, newCurrentType, paramno);
8371 if (ctype_isMissingParamsMarker (newCurrentType)
8372 || ctype_isElips (newCurrentType)
8373 || ctype_isMissingParamsMarker (oldCurrentType)
8374 || ctype_isElips (oldCurrentType))
8380 if (ctype_isConj (newCurrentType))
8382 if (ctype_isConj (oldCurrentType))
8384 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8388 message ("Parameter %q inconsistently %rdeclared with "
8389 "alternate types %s "
8390 "(types match, but alternates are not identical, "
8391 "so checking may not be correct)",
8392 uentry_getName (newCurrent),
8393 uentry_isDeclared (oldCurrent),
8394 ctype_unparse (newCurrentType)),
8395 uentry_whereDeclared (unew)))
8397 uentry_showWhereLastVal (oldCurrent,
8398 ctype_unparse (oldCurrentType));
8406 message ("Parameter %q inconsistently %rdeclared with "
8407 "alternate types %s",
8408 uentry_getName (newCurrent),
8409 uentry_isDeclared (oldCurrent),
8410 ctype_unparse (newCurrentType)),
8411 uentry_whereDeclared (unew)))
8413 uentry_showWhereLastVal (oldCurrent,
8414 ctype_unparse (oldCurrentType));
8421 if (ctype_isConj (oldCurrentType))
8423 uentry_setType (newCurrent, oldCurrentType);
8431 ** Forgot this! detected by lclint:
8432 ** uentry.c:1257,15: Suspected infinite loop
8438 if (!uentryList_isMissingParams (newParams))
8440 if (ctype_isConj (oldRetType))
8442 old->utype = ctype_makeFunction (oldRetType,
8443 uentryList_copy (newParams));
8447 old->utype = unew->utype;
8451 checkGlobalsConformance (old, unew, mustConform, completeConform);
8452 checkModifiesConformance (old, unew, mustConform, completeConform);
8454 DPRINTF (("Before list: %s",
8455 uentry_unparseFull (old)));
8457 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8459 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8464 message ("Function %q redeclared using special clauses (can only "
8465 "be used in first declaration)",
8466 uentry_getName (unew)),
8467 uentry_whereDeclared (unew)))
8469 uentry_showWhereLast (old);
8473 /*@i23 need checking @*/
8475 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8479 /*@i43 should be able to append? @*/
8481 stateClauseList_checkEqual (old, unew);
8482 stateClauseList_free (unew->info->fcn->specclauses);
8483 unew->info->fcn->specclauses = stateClauseList_undefined;
8486 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8489 if (fileloc_isUndefined (old->whereDeclared))
8491 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8493 else if (fileloc_isUndefined (unew->whereDeclared))
8495 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8504 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8508 llassert (uentry_isValid (ue));
8509 llassert (uentry_isEitherConstant (ue));
8511 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8512 uval = uentry_getConstantValue (ue);
8514 if (multiVal_isDefined (uval))
8516 if (multiVal_isDefined (m))
8518 if (!multiVal_equiv (uval, m))
8522 message ("%s %q defined with inconsistent value: %q",
8523 ekind_capName (ue->ukind),
8524 uentry_getName (ue),
8525 multiVal_unparse (m)),
8528 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8536 uentry_setConstantValue (ue, m);
8541 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8544 bool typeError = FALSE;
8546 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8548 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8552 DPRINTF (("Check struct conformance: %s / %s",
8553 uentry_unparseFull (old),
8554 uentry_unparseFull (unew)));
8555 checkStructConformance (old, unew);
8560 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8562 llbug (message ("struct tags: bad types: %t / %t",
8563 old->utype, unew->utype));
8567 else if (uentry_isEnumTag (old))
8569 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8571 if (mustConform) checkEnumConformance (old, unew);
8575 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8577 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8578 ctype_unparse (unew->utype)));
8582 else if (!ctype_match (old->utype, unew->utype))
8584 DPRINTF (("Type mismatch: %s / %s",
8585 ctype_unparse (old->utype),
8586 ctype_unparse (unew->utype)));
8588 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8590 ctype realt = ctype_realType (unew->utype);
8592 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8594 unew->utype = ctype_bool;
8600 typeError = optgenerror
8602 message ("%q defined as %s", uentry_getName (old),
8603 ctype_unparse (realt)),
8604 uentry_whereDeclared (unew));
8612 ctype oldr = ctype_realType (old->utype);
8613 ctype newr = ctype_realType (unew->utype);
8615 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8617 checkStructConformance (old, unew);
8619 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8621 checkStructConformance (old, unew);
8623 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8625 checkEnumConformance (old, unew);
8627 else if (uentry_isConstant (old)
8628 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8630 /* okay...for now! (should check the type is reset later... */
8634 DPRINTF (("YABA!"));
8637 message ("%s %q %rdeclared with inconsistent type: %t",
8638 ekind_capName (unew->ukind),
8639 uentry_getName (unew),
8640 uentry_isDeclared (old),
8642 uentry_whereDeclared (unew)))
8644 uentry_showWhereLast (old);
8660 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8661 /*@notnull@*/ uentry unew,
8662 bool mustConform, bool completeConform)
8664 if (ctype_isDefined (unew->info->datatype->type))
8667 ** bool is hard coded here, since it is built into LCL.
8668 ** For now, we're stuck with LCL's types.
8671 if (ctype_isDirectBool (old->utype) &&
8672 cstring_equalLit (unew->uname, "bool"))
8674 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8675 evs 2000-07-25: removed
8677 unew->utype = ctype_bool;
8680 if (ctype_isUnknown (old->info->datatype->type))
8682 old->info->datatype->type = unew->info->datatype->type;
8686 DPRINTF (("Old: %s / New: %s",
8687 uentry_unparseFull (old),
8688 uentry_unparseFull (unew)));
8689 DPRINTF (("Types: %s / %s",
8690 ctype_unparse (old->info->datatype->type),
8691 ctype_unparse (unew->info->datatype->type)));
8693 if (ctype_matchDef (old->info->datatype->type,
8694 unew->info->datatype->type))
8703 ("Type %q %s with inconsistent type: %t",
8704 uentry_getName (unew),
8705 uentry_reDefDecl (old, unew),
8706 unew->info->datatype->type),
8707 uentry_whereDeclared (unew)))
8709 uentry_showWhereLastExtra
8710 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8713 old->info->datatype->type = unew->info->datatype->type;
8718 if (unew->info->datatype->abs != MAYBE)
8720 if (ynm_isOff (old->info->datatype->abs)
8721 && ynm_isOn (unew->info->datatype->abs))
8723 if (!ctype_isDirectBool (old->utype))
8728 ("Datatype %q inconsistently %rdeclared as abstract type",
8729 uentry_getName (unew),
8730 uentry_isDeclared (old)),
8731 uentry_whereDeclared (unew)))
8733 uentry_showWhereLastPlain (old);
8737 else if (ynm_isOn (old->info->datatype->abs)
8738 && ynm_isOff (unew->info->datatype->abs))
8740 if (!ctype_isDirectBool (old->utype))
8745 ("Datatype %q inconsistently %rdeclared as concrete type",
8746 uentry_getName (unew),
8747 uentry_isDeclared (old)),
8748 uentry_whereDeclared (unew)))
8750 uentry_showWhereLastPlain (old);
8761 if (ynm_isOn (old->info->datatype->abs))
8763 old->sref = unew->sref;
8764 unew->info->datatype->mut = old->info->datatype->mut;
8767 && uentry_isReallySpecified (old))
8772 ("Datatype %q specified as abstract, "
8773 "but abstract annotation not used in declaration",
8774 uentry_getName (unew)),
8775 uentry_whereDeclared (unew)))
8777 uentry_showWhereLastPlain (old);
8783 unew->info->datatype->abs = old->info->datatype->abs;
8785 if (ynm_isMaybe (unew->info->datatype->mut))
8787 if (completeConform && ynm_isOff (old->info->datatype->mut)
8788 && uentry_isReallySpecified (old))
8793 ("Datatype %q specified as immutable, "
8794 "but immutable annotation not used in declaration",
8795 uentry_getName (unew)),
8796 uentry_whereDeclared (unew)))
8798 uentry_showWhereLastPlain (old);
8802 unew->info->datatype->mut = old->info->datatype->mut;
8804 else if (ynm_isMaybe (old->info->datatype->mut))
8806 old->info->datatype->mut = unew->info->datatype->mut;
8810 if (ynm_isOn (old->info->datatype->abs))
8812 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8816 message ("Datatype %q inconsistently %rdeclared as immutable",
8817 uentry_getName (unew),
8818 uentry_isDeclared (old)),
8819 uentry_whereDeclared (unew)))
8821 uentry_showWhereLastPlain (old);
8826 if (ynm_isOff (old->info->datatype->mut)
8827 && ynm_isOn (unew->info->datatype->mut))
8831 message ("Datatype %q inconsistently %rdeclared as mutable",
8832 uentry_getName (unew),
8833 uentry_isDeclared (old)),
8834 uentry_whereDeclared (unew)))
8836 uentry_showWhereLastPlain (old);
8841 old->info->datatype->mut = unew->info->datatype->mut;
8844 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8848 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8849 /*@notnull@*/ uentry unew,
8851 /*@unused@*/ bool completeConform)
8853 multiVal oldval = uentry_getConstantValue (old);
8854 multiVal newval = uentry_getConstantValue (unew);
8856 if (multiVal_isDefined (oldval))
8858 if (multiVal_isDefined (newval))
8860 if (!multiVal_equiv (oldval, newval))
8865 message ("%s %q %rdeclared with inconsistent value: %q",
8866 ekind_capName (unew->ukind),
8867 uentry_getName (unew),
8868 uentry_isDeclared (old),
8869 multiVal_unparse (newval)),
8870 uentry_whereDeclared (unew)))
8872 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8876 uentry_setConstantValue (unew, multiVal_copy (oldval));
8885 uentry_setConstantValue (old, multiVal_copy (newval));
8890 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8891 /*@notnull@*/ uentry unew, bool mustConform,
8892 bool completeConform)
8894 bool typeError = FALSE;
8895 bool fcnConformance = FALSE;
8897 if (!ekind_equal (unew->ukind, old->ukind))
8900 ** okay, only if one is a function and the other is
8901 ** a variable of type function.
8904 if (unew->ukind == KENUMCONST
8905 && old->ukind == KCONST)
8907 old->ukind = KENUMCONST;
8911 if (unew->ukind == KFCN
8912 && old->ukind == KCONST
8913 && ctype_isUnknown (old->utype))
8916 ** When a function is defined with an unparam macro
8919 uentry_updateInto (old, unew);
8923 if (uentry_isExpandedMacro (old)
8924 && uentry_isEitherConstant (unew))
8926 uentry_updateInto (old, unew);
8930 if (uentry_isEndIter (unew))
8932 if (ctype_isUnknown (old->utype))
8934 if (!uentry_isSpecified (old)
8935 && uentry_isCodeDefined (unew))
8937 if (!fileloc_withinLines (uentry_whereDefined (old),
8938 uentry_whereDeclared (unew), 2))
8939 { /* bogus! will give errors if there is too much whitespace */
8943 ("Iterator finalized name %q does not match name in "
8944 "previous iter declaration (should be end_%q). This iter "
8945 "is declared at %q",
8946 uentry_getName (unew),
8947 uentry_getName (old),
8948 fileloc_unparse (uentry_whereDefined (old))),
8949 uentry_whereDeclared (old));
8953 uentry_updateInto (old, unew);
8958 KindConformanceError (old, unew, mustConform);
8962 if (uentry_isFunction (unew))
8964 if (uentry_isVariable (old))
8966 if (!ctype_isUnknown (old->utype))
8968 if (ctype_isFunction (old->utype))
8970 uentry_makeVarFunction (old);
8971 checkFunctionConformance (old, unew, mustConform,
8973 fcnConformance = TRUE;
8977 KindConformanceError (old, unew, mustConform);
8982 if (uentry_isExpandedMacro (old))
8984 if (fileloc_isUndefined (unew->whereDefined))
8986 unew->whereDefined = fileloc_update (unew->whereDefined,
8990 uentry_updateInto (old, unew);
8991 old->used = unew->used = TRUE;
8996 /* undeclared identifier */
8997 old->utype = unew->utype;
8998 uentry_makeVarFunction (old);
8999 checkFunctionConformance (old, unew, FALSE, FALSE);
9000 fcnConformance = TRUE;
9006 KindConformanceError (old, unew, mustConform);
9009 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9011 if (!ctype_isUnknown (unew->utype))
9013 if (ctype_isFunction (unew->utype))
9015 uentry_makeVarFunction (unew);
9016 checkFunctionConformance (old, unew, mustConform, completeConform);
9017 fcnConformance = TRUE;
9021 KindConformanceError (old, unew, mustConform);
9026 KindConformanceError (old, unew, mustConform);
9031 KindConformanceError (old, unew, mustConform);
9037 ** check parameter lists for functions
9038 ** (before type errors, to get better messages
9041 if (uentry_isFunction (old))
9043 checkFunctionConformance (old, unew, mustConform, completeConform);
9044 fcnConformance = TRUE;
9048 if (!ctype_isUndefined (old->utype))
9050 typeError = checkTypeConformance (old, unew, mustConform);
9057 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9059 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9062 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9064 DPRINTF (("Check datatype: %s / %s",
9065 uentry_unparseFull (old),
9066 uentry_unparseFull (unew)));
9068 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9071 if (uentry_isVariable (old) && uentry_isVariable (unew))
9074 !ctype_matchDef (old->utype, unew->utype))
9079 ("Variable %q %s with inconsistent type (arrays and pointers are "
9080 "not identical in variable declarations): %t",
9081 uentry_getName (unew),
9082 uentry_reDefDecl (old, unew),
9084 uentry_whereDeclared (unew)))
9086 uentry_showWhereLast (old);
9089 ** Avoid repeated errors.
9092 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9094 old->whereDefined = fileloc_update (old->whereDefined,
9102 checkVarConformance (old, unew, mustConform, completeConform);
9107 /* old->utype = unew->utype; */
9111 if (ctype_isConj (old->utype))
9113 if (ctype_isConj (unew->utype))
9115 if (!ctype_sameAltTypes (old->utype, unew->utype))
9119 message ("%s %q inconsistently %rdeclared with "
9120 "alternate types %s "
9121 "(types match, but alternates are not identical, "
9122 "so checking may not be correct)",
9123 ekind_capName (uentry_getKind (old)),
9124 uentry_getName (unew),
9125 uentry_isDeclared (old),
9126 ctype_unparse (unew->utype)),
9127 uentry_whereDeclared (unew)))
9129 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9133 old->utype = unew->utype;
9140 if (ctype_isUnknown (old->utype))
9142 old->utype = unew->utype;
9147 if (unew->ukind == old->ukind)
9150 unew->info = uinfo_copy (old->info, old->ukind);
9153 sRef_storeState (old->sref);
9154 sRef_storeState (unew->sref);
9157 static void uentry_mergeConstraints (uentry spec, uentry def)
9159 if (uentry_isFunction (def))
9161 DPRINTF (("Here: %s / %s",
9162 uentry_unparseFull (spec),
9163 uentry_unparseFull (def)));
9164 /* evans 2001-07-21 */
9165 llassert (uentry_isFunction (spec));
9167 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9169 if (fileloc_isXHFile (uentry_whereLast (def)))
9171 llassert (uentry_isFunction (spec));
9172 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9173 def->info->fcn->preconditions);
9175 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9181 /* Check if the constraints are identical */
9186 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9187 uentry_getName (spec),
9188 functionConstraint_unparse (spec->info->fcn->preconditions)),
9189 uentry_whereLast (def)))
9191 uentry_showWhereSpecified (spec);
9194 functionConstraint_free (spec->info->fcn->preconditions);
9195 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9198 def->info->fcn->preconditions = functionConstraint_undefined;
9201 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9203 if (fileloc_isXHFile (uentry_whereLast (def)))
9205 llassert (uentry_isFunction (spec));
9206 DPRINTF (("Post: %s /++/ %s",
9207 functionConstraint_unparse (spec->info->fcn->postconditions),
9208 functionConstraint_unparse (def->info->fcn->postconditions)));
9209 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9210 def->info->fcn->postconditions);
9211 def->info->fcn->postconditions = functionConstraint_undefined;
9212 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9219 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9220 uentry_getName (spec),
9221 functionConstraint_unparse (spec->info->fcn->postconditions)),
9222 uentry_whereLast (def)))
9224 uentry_showWhereSpecified (spec);
9227 functionConstraint_free (spec->info->fcn->postconditions);
9228 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9229 def->info->fcn->postconditions = functionConstraint_undefined;
9236 ** modifies spec to reflect def, reports any inconsistencies
9240 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9242 llassert (uentry_isValid (spec));
9243 llassert (uentry_isValid (def));
9244 llassert (cstring_equal (spec->uname, def->uname));
9246 if (uentry_isFunction (def))
9248 if (uentry_isConstant (spec))
9250 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9251 uentry_makeConstantFunction (spec);
9255 uentry_convertVarFunction (spec);
9258 llassert (uentry_isFunction (spec));
9261 DPRINTF (("Merge entries: %s / %s",
9262 uentry_unparseFull (spec),
9263 uentry_unparseFull (def)));
9265 uentry_mergeConstraints (spec, def);
9267 uentry_checkConformance (spec, def, TRUE,
9268 context_getFlag (FLG_NEEDSPEC));
9270 DPRINTF (("Merge entries after conform: %s / %s",
9271 uentry_unparseFull (spec),
9272 uentry_unparseFull (def)));
9274 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9277 ** okay, declarations conform. Propagate extra information.
9280 uentry_setDefined (spec, uentry_whereDefined (def));
9281 uentry_setDeclared (spec, uentry_whereDeclared (def));
9283 if (uentry_isStatic (def))
9287 message ("%s %q specified, but declared as static",
9288 ekind_capName (def->ukind),
9289 uentry_getName (def)),
9290 uentry_whereDeclared (def)))
9292 uentry_showWhereSpecified (spec);
9297 spec->storageclass = def->storageclass;
9300 sRef_storeState (spec->sref);
9302 spec->used = def->used || spec->used;
9303 spec->hasNameError |= def->hasNameError;
9307 if (!spec->hasNameError)
9309 uentry_checkName (spec);
9318 ** Can't generate function redeclaration errors when the
9319 ** entries are merged, since we don't yet know if its the
9320 ** definition of the function.
9324 uentry_clearDecl (void)
9326 posRedeclared = uentry_undefined;
9327 fileloc_free (posLoc);
9328 posLoc = fileloc_undefined;
9332 uentry_checkDecl (void)
9334 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9336 llassert (fileloc_isDefined (posLoc));
9338 if (uentry_isCodeDefined (posRedeclared))
9340 if (optgenerror (FLG_REDECL,
9341 message ("%s %q declared after definition",
9342 ekind_capName (posRedeclared->ukind),
9343 uentry_getName (posRedeclared)),
9346 llgenindentmsg (message ("Definition of %q",
9347 uentry_getName (posRedeclared)),
9348 posRedeclared->whereDeclared);
9353 if (optgenerror (FLG_REDECL,
9354 message ("%s %q declared more than once",
9355 ekind_capName (posRedeclared->ukind),
9356 uentry_getName (posRedeclared)),
9359 llgenindentmsg (message ("Previous declaration of %q",
9360 uentry_getName (posRedeclared)),
9361 posRedeclared->whereDeclared);
9366 fileloc_free (posLoc);
9367 posLoc = fileloc_undefined;
9368 posRedeclared = uentry_undefined;
9372 ** Redefinition of old as unew.
9373 ** modifies old to reflect unew, reports any inconsistencies
9377 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9379 fileloc olddef = uentry_whereDeclared (old);
9380 fileloc unewdef = uentry_whereDeclared (unew);
9384 DPRINTF (("uentry merge: %s / %s",
9385 uentry_unparseFull (old),
9386 uentry_unparseFull (unew)));
9389 fileloc_isUndefined (olddef)
9390 && fileloc_isDefined (uentry_whereDefined (old))
9391 && !uentry_isExpandedMacro (old);
9393 if (!context_getFlag (FLG_INCONDEFSLIB)
9394 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9396 mustConform = FALSE;
9403 llassert (uentry_isValid (old));
9404 llassert (uentry_isValid (unew));
9405 llassert (cstring_equal (old->uname, unew->uname));
9407 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9409 if (uentry_isConstant (old))
9411 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9412 uentry_makeConstantFunction (old);
9416 uentry_convertVarFunction (old);
9419 llassert (uentry_isFunction (old));
9422 DPRINTF (("uentry merge: %s / %s",
9423 uentry_unparseFull (old),
9424 uentry_unparseFull (unew)));
9426 if (uentry_isExtern (unew))
9428 uentry_setUsed (old, unewdef);
9432 ** should check old one was extern!
9435 if (uentry_isStatic (old))
9437 if (!(uentry_isStatic (unew)))
9441 message ("%s %q shadows static declaration",
9442 ekind_capName (unew->ukind),
9443 uentry_getName (unew)),
9446 uentry_showWhereLast (old);
9451 uentry_setDeclDef (old, unewdef);
9454 else if (uentry_isStatic (unew))
9456 uentry_setDeclDef (old, unewdef);
9458 else if (uentry_isExtern (old))
9460 uentry_setDeclared (old, unewdef);
9464 if (!uentry_isExtern (unew)
9465 && !uentry_isForward (old)
9466 && !fileloc_equal (olddef, unewdef)
9467 && !fileloc_isUndefined (olddef)
9468 && !fileloc_isUndefined (unewdef)
9469 && !fileloc_isBuiltin (olddef)
9470 && !fileloc_isBuiltin (unewdef)
9471 && !uentry_isYield (old)
9472 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9474 if (uentry_isVariable (old) || uentry_isVariable (unew))
9476 ; /* will report redeclaration error later */
9480 if (fileloc_isDefined (uentry_whereDefined (old)))
9484 message ("%s %q defined more than once",
9485 ekind_capName (unew->ukind),
9486 uentry_getName (unew)),
9487 uentry_whereLast (unew)))
9490 (message ("Previous definition of %q",
9491 uentry_getName (old)),
9492 uentry_whereLast (old));
9495 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9497 uentry_updateInto (old, unew);
9498 old->sref = sRef_saveCopy (old->sref);
9506 if (fileloc_isLib (olddef)
9507 || fileloc_isUndefined (olddef)
9508 || fileloc_isImport (olddef))
9510 if (uentry_isExtern (unew))
9512 if (uentry_isExtern (old)
9513 || (fileloc_isDefined (uentry_whereDeclared (old))
9514 && (!fileloc_equal (uentry_whereDeclared (old),
9515 uentry_whereDefined (old)))))
9519 message ("%s %q declared more than once",
9520 ekind_capName (unew->ukind),
9521 uentry_getName (unew)),
9522 unew->whereDeclared))
9525 (message ("Previous declaration of %q",
9526 uentry_getName (old)),
9527 old->whereDeclared);
9531 uentry_setExtern (old);
9535 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9541 DPRINTF (("uentry merge: %s / %s",
9542 uentry_unparseFull (old),
9543 uentry_unparseFull (unew)));
9545 uentry_mergeConstraints (old, unew);
9546 DPRINTF (("uentry merge: %s / %s",
9547 uentry_unparseFull (old),
9548 uentry_unparseFull (unew)));
9550 uentry_checkConformance (old, unew, mustConform, FALSE);
9551 DPRINTF (("uentry merge: %s / %s",
9552 uentry_unparseFull (old),
9553 uentry_unparseFull (unew)));
9555 old->used = old->used || unew->used;
9556 old->uses = filelocList_append (old->uses, unew->uses);
9557 unew->uses = filelocList_undefined;
9559 sRef_storeState (old->sref);
9560 sRef_storeState (unew->sref);
9564 old->whereDefined = fileloc_update (old->whereDefined,
9568 DPRINTF (("here: %s", uentry_unparseFull (old)));
9571 ** No redeclaration errors for functions here, since we
9572 ** don't know if this is the definition of the function.
9575 if (fileloc_isUser (old->whereDeclared)
9576 && fileloc_isUser (unew->whereDeclared)
9577 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9578 && !fileloc_isDefined (unew->whereDefined))
9580 if (uentry_isFunction (old))
9582 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9583 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9587 if (optgenerror (FLG_REDECL,
9588 message ("%s %q declared more than once",
9589 ekind_capName (unew->ukind),
9590 uentry_getName (unew)),
9591 unew->whereDeclared))
9593 llgenindentmsg (message ("Previous declaration of %q",
9594 uentry_getName (old)),
9595 old->whereDeclared);
9600 if (fileloc_isUndefined (old->whereDefined))
9602 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9606 if (!context_processingMacros ()
9607 && fileloc_isUser (old->whereDefined)
9608 && fileloc_isUser (unew->whereDefined)
9609 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9611 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9613 if (uentry_isVariable (unew)
9614 && uentry_isExtern (unew))
9616 if (optgenerror (FLG_REDECL,
9617 message ("%s %q declared after definition",
9618 ekind_capName (unew->ukind),
9619 uentry_getName (unew)),
9620 unew->whereDeclared))
9622 llgenindentmsg (message ("Definition of %q",
9623 uentry_getName (old)),
9629 if (optgenerror (FLG_REDEF,
9630 message ("%s %q redefined",
9631 ekind_capName (unew->ukind),
9632 uentry_getName (unew)),
9633 unew->whereDefined))
9635 llgenindentmsg (message ("Previous definition of %q",
9636 uentry_getName (old)),
9644 if (uentry_isExternal (unew))
9646 old->whereDefined = fileloc_createExternal ();
9649 if (unew->hasNameError)
9651 old->hasNameError = TRUE;
9656 if (!old->hasNameError)
9658 uentry_checkName (old);
9661 DPRINTF (("After: %s", uentry_unparseFull (old)));
9662 llassert (!ctype_isUndefined (old->utype));
9666 uentry_copyState (uentry res, uentry other)
9668 llassert (uentry_isValid (res));
9669 llassert (uentry_isValid (other));
9671 res->used = other->used;
9673 res->info->var->kind = other->info->var->kind;
9674 res->info->var->defstate = other->info->var->defstate;
9675 res->info->var->nullstate = other->info->var->nullstate;
9676 res->info->var->checked = other->info->var->checked;
9678 sRef_copyState (res->sref, other->sref);
9682 uentry_sameKind (uentry u1, uentry u2)
9684 if (uentry_isValid (u1) && uentry_isValid (u2))
9686 if (uentry_isVar (u1) && uentry_isVar (u2))
9688 ctype c1 = u1->utype;
9689 ctype c2 = u2->utype;
9691 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9694 ** both functions, or both not functions
9697 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9701 return ((u1->ukind == u2->ukind));
9708 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9710 ekind okind = unew->ukind;
9711 llassert (uentry_isValid (unew));
9712 llassert (uentry_isValid (old));
9714 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9716 unew->ukind = old->ukind;
9717 llassert (cstring_equal (unew->uname, old->uname));
9718 unew->utype = old->utype;
9720 if (fileloc_isDefined (unew->whereSpecified)
9721 && !fileloc_isDefined (old->whereSpecified))
9723 ; /* Keep the old value */
9727 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9728 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9731 if (fileloc_isDefined (unew->whereDefined)
9732 && !fileloc_isDefined (old->whereDefined))
9734 ; /* Keep the old value */
9738 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9739 unew->whereDefined = fileloc_copy (old->whereDefined);
9742 if (fileloc_isDefined (unew->whereDeclared)
9743 && !fileloc_isDefined (old->whereDeclared))
9745 ; /* Keep the old value */
9749 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9750 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9753 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9755 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9756 unew->used = old->used;
9758 unew->isPrivate = old->isPrivate;
9759 unew->hasNameError = old->hasNameError;
9760 unew->uses = filelocList_append (unew->uses, old->uses);
9761 old->uses = filelocList_undefined;
9763 unew->storageclass = old->storageclass;
9764 uinfo_free (unew->info, okind);
9765 unew->info = uinfo_copy (old->info, old->ukind);
9770 uentry_copy (uentry e)
9772 if (uentry_isValid (e))
9774 uentry enew = uentry_alloc ();
9775 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9776 enew->ukind = e->ukind;
9777 enew->uname = cstring_copy (e->uname);
9778 enew->utype = e->utype;
9780 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9781 enew->whereDefined = fileloc_copy (e->whereDefined);
9782 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9784 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9785 enew->used = e->used;
9787 enew->isPrivate = e->isPrivate;
9788 enew->hasNameError = e->hasNameError;
9789 enew->uses = filelocList_undefined;
9791 enew->storageclass = e->storageclass;
9792 enew->info = uinfo_copy (e->info, e->ukind);
9793 enew->warn = warnClause_copy (e->warn);
9795 DPRINTF (("Here we are..."));
9796 DPRINTF (("original: %s", uentry_unparseFull (e)));
9797 DPRINTF (("copy: %s", uentry_unparse (enew)));
9798 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9803 return uentry_undefined;
9808 uentry_setState (uentry res, uentry other)
9810 llassert (uentry_isValid (res));
9811 llassert (uentry_isValid (other));
9813 llassert (res->ukind == other->ukind);
9814 llassert (res->ukind == KVAR);
9816 res->sref = sRef_saveCopy (other->sref);
9817 res->used = other->used;
9818 filelocList_free (res->uses);
9819 res->uses = other->uses;
9820 other->uses = filelocList_undefined;
9821 res->lset = other->lset;
9825 uentry_mergeUses (uentry res, uentry other)
9827 llassert (uentry_isValid (res));
9828 llassert (uentry_isValid (other));
9830 res->used = other->used || res->used;
9831 res->lset = other->lset || res->lset;
9832 res->uses = filelocList_append (res->uses, other->uses);
9833 other->uses = filelocList_undefined;
9838 ** This is a really ugly routine.
9840 ** gack...fix this one day.
9845 ** >> res is the false branch, other is the true branch (or continuation)
9847 ** >> res is the true branch, other is the false branch (or continutation)
9854 ** References not effected by res are propagated from other.
9858 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9859 bool flip, clause cl, fileloc loc)
9863 message ("%s %q is %s %s, but %s %s.",
9864 ekind_capName (res->ukind), uentry_getName (res),
9865 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9866 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9869 if (sRef_isDead (res->sref))
9871 sRef_showStateInfo (res->sref);
9873 else if (sRef_isKept (res->sref))
9875 sRef_showAliasInfo (res->sref);
9877 else /* dependent */
9879 sRef_showAliasInfo (res->sref);
9880 sRef_showAliasInfo (other->sref);
9883 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9887 static bool incompatibleStates (sRef rs, sRef os)
9889 alkind rk = sRef_getAliasKind (rs);
9890 alkind ok = sRef_getAliasKind (os);
9892 if (alkind_isError (rk) || alkind_isError (ok))
9898 return ((sRef_isDead (rs)
9899 || (alkind_isKept (rk) && !alkind_isKept (ok))
9900 || (alkind_isDependent (rk)
9901 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9902 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9907 branchStateAltError (/*@notnull@*/ uentry res,
9908 /*@notnull@*/ uentry other, bool flip,
9909 clause cl, fileloc loc)
9913 message ("%s %q is %s %s, but %s %s.",
9914 ekind_capName (res->ukind), uentry_getName (res),
9915 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
9916 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
9919 if (sRef_isDead (other->sref))
9921 sRef_showStateInfo (other->sref);
9925 sRef_showAliasInfo (other->sref);
9928 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9929 sRef_setDefinedComplete (res->sref, fileloc_undefined);
9931 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
9932 sRef_setDefinedComplete (other->sref, fileloc_undefined);
9937 ** A reference is relevant for certain checks, only if it
9938 ** is not definitely null on this path (but not declared
9939 ** to always be null.)
9942 static bool uentry_relevantReference (sRef sr, bool flip)
9944 if (sRef_isKept (sr) || sRef_isDependent (sr))
9952 return !sRef_definitelyNullContext (sr);
9956 return !sRef_definitelyNullAltContext (sr);
9962 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
9963 bool mustReturn, bool flip, bool opt,
9966 DPRINTF (("Merge alias states: %s / %s",
9967 uentry_unparseFull (res),
9968 uentry_unparseFull (other)));
9970 if (sRef_isValid (res->sref))
9975 if (incompatibleStates (res->sref, other->sref))
9979 if (sRef_isThroughArrayFetch (res->sref)
9980 && !context_getFlag (FLG_STRICTBRANCHSTATE))
9982 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
9984 sRef_maybeKill (res->sref, loc);
9986 else if (sRef_isPossiblyDead (other->sref))
9988 sRef_maybeKill (res->sref, loc);
9997 if (uentry_relevantReference (other->sref, flip))
10000 if (sRef_isLocalParamVar (res->sref)
10001 && (sRef_isLocalState (other->sref)
10002 || sRef_isDependent (other->sref)))
10004 if (sRef_isDependent (res->sref))
10006 sRef_setDependent (other->sref, loc);
10010 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
10015 branchStateError (res, other, flip, cl, loc);
10020 if (sRef_isKept (res->sref))
10022 sRef_setKept (other->sref, loc);
10027 if (incompatibleStates (other->sref, res->sref))
10029 if (uentry_relevantReference (res->sref, !flip))
10031 if (sRef_isLocalParamVar (res->sref)
10032 && (sRef_isDependent (res->sref)
10033 || sRef_isLocalState (res->sref)))
10035 if (sRef_isDependent (other->sref))
10037 sRef_setDependent (res->sref, loc);
10041 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
10046 if (sRef_isParam (other->sref))
10049 ** If the local variable associated
10050 ** with the param has the correct state,
10052 ** (e.g., free (s); s = new(); ...
10055 uentry uvar = usymtab_lookupSafe (other->uname);
10057 if (uentry_isValid (uvar)
10058 && ((sRef_isDead (other->sref)
10059 && sRef_isOnly (uvar->sref))
10060 || (sRef_isDependent (other->sref)
10061 && sRef_isOwned (uvar->sref))))
10067 branchStateAltError (res, other,
10073 DPRINTF (("Here: %s / %s",
10074 uentry_unparseFull (res),
10075 uentry_unparseFull (other)));
10077 branchStateAltError (res, other,
10084 if (sRef_isKept (other->sref))
10086 sRef_setKept (res->sref, loc);
10092 DPRINTF (("Merge opt..."));
10093 sRef_mergeOptState (res->sref, other->sref, cl, loc);
10094 DPRINTF (("Done!"));
10098 sRef_mergeState (res->sref, other->sref, cl, loc);
10103 if (sRef_isModified (other->sref))
10105 sRef_setModified (res->sref);
10112 uentry_mergeValueStates (uentry res, uentry other, fileloc loc)
10114 valueTable rvalues;
10115 valueTable ovalues;
10117 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10119 rvalues = sRef_getValueTable (res->sref);
10120 ovalues = sRef_getValueTable (other->sref);
10122 if (valueTable_isUndefined (ovalues))
10124 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10127 else if (valueTable_isUndefined (rvalues))
10130 ** Copy values from other
10134 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10135 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10140 valueTable_elements (ovalues, fkey, fval) {
10142 metaStateInfo minfo;
10143 stateCombinationTable sctable;
10147 tval = valueTable_lookup (rvalues, fkey);
10149 DPRINTF (("Merge value: %s / %s X %s", fkey,
10150 stateValue_unparse (fval), stateValue_unparse (tval)));
10152 minfo = context_lookupMetaStateInfo (fkey);
10153 llassert (stateValue_isDefined (tval));
10155 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10157 DPRINTF (("Cannot find meta state for: %s", fkey));
10162 llassert (metaStateInfo_isDefined (minfo));
10164 if (stateValue_isError (fval)
10165 || sRef_definitelyNullContext (res->sref))
10167 sRef_setMetaStateValueComplete (res->sref,
10168 fkey, stateValue_getValue (fval),
10170 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10172 else if (stateValue_isError (tval)
10173 || sRef_definitelyNullAltContext (other->sref))
10175 DPRINTF (("Other branch is definitely null!"));
10179 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10180 metaStateInfo_unparse (minfo),
10181 stateValue_unparse (fval),
10182 stateValue_unparse (tval)));
10184 DPRINTF (("state values: %d / %d",
10185 stateValue_getValue (fval), stateValue_getValue (tval)));
10187 sctable = metaStateInfo_getMergeTable (minfo);
10189 DPRINTF (("Merge table: %s",
10190 stateCombinationTable_unparse (sctable)));
10192 msg = cstring_undefined;
10194 nval = stateCombinationTable_lookup (sctable,
10195 stateValue_getValue (fval),
10196 stateValue_getValue (tval),
10199 DPRINTF (("nval: %d / %d / %d", nval,
10200 stateValue_getValue (fval), stateValue_getValue (tval)));
10202 if (cstring_isDefined (msg))
10204 /*@i32 print extra info for assignments@*/
10206 if (uentry_isGlobalMarker (res))
10211 ("Control branches merge with incompatible global states (%s and %s): %s",
10212 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10213 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10217 sRef_showMetaStateInfo (res->sref, fkey);
10218 sRef_showMetaStateInfo (other->sref, fkey);
10226 ("Control branches merge with incompatible states for %q (%s and %s): %s",
10227 uentry_getName (res),
10228 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10229 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10233 sRef_showMetaStateInfo (res->sref, fkey);
10234 sRef_showMetaStateInfo (other->sref, fkey);
10235 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10236 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10237 DPRINTF (("Null: %s / %s",
10238 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10239 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10245 if (nval == stateValue_getValue (fval)
10246 && nval != stateValue_getValue (tval))
10248 loc = stateValue_getLoc (fval);
10250 else if (nval == stateValue_getValue (tval)
10251 && nval != stateValue_getValue (fval))
10253 loc = stateValue_getLoc (tval);
10260 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10261 && nval == stateValue_getValue (fval)
10262 && nval == stateValue_getValue (tval))
10268 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10272 } end_valueTable_elements ;
10278 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10279 bool flip, clause cl)
10281 if (cl == DOWHILECLAUSE)
10283 res->used = other->used || res->used;
10284 res->lset = other->lset || res->lset;
10285 res->uses = filelocList_append (res->uses, other->uses);
10286 other->uses = filelocList_undefined;
10290 if (sRef_isMacroParamRef (res->sref)
10291 && !uentry_isSefParam (other)
10292 && !uentry_isSefParam (res))
10294 bool hasError = FALSE;
10296 if (bool_equal (res->used, other->used))
10298 res->used = other->used;
10302 if (other->used && !flip)
10307 message ("Macro parameter %q used in true clause, "
10308 "but not in false clause",
10309 uentry_getName (res)),
10310 uentry_whereDeclared (res));
10317 message ("Macro parameter %q used in false clause, "
10318 "but not in true clause",
10319 uentry_getName (res)),
10320 uentry_whereDeclared (res));
10326 /* make it sef now, prevent more errors */
10327 res->info->var->kind = VKREFSEFPARAM;
10333 res->used = other->used || res->used;
10334 res->lset = other->lset || res->lset;
10335 res->uses = filelocList_append (res->uses, other->uses);
10336 other->uses = filelocList_undefined;
10342 uentry_mergeState (uentry res, uentry other, fileloc loc,
10343 bool mustReturn, bool flip, bool opt,
10346 llassert (uentry_isValid (res));
10347 llassert (uentry_isValid (other));
10349 llassert (res->ukind == other->ukind);
10350 llassert (res->ukind == KVAR);
10352 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10353 uentry_unparseFull (other)));
10355 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10356 uentry_mergeValueStates (res, other, loc);
10357 uentry_mergeSetStates (res, other, loc, flip, cl);
10360 void uentry_setUsed (uentry e, fileloc loc)
10362 static bool firstTime = TRUE;
10363 static bool showUses = FALSE;
10364 static bool exportLocal = FALSE;
10366 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10370 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10372 showUses = context_getFlag (FLG_SHOWUSES);
10373 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10378 if (uentry_isValid (e))
10382 if (warnClause_isDefined (e->warn))
10384 flagSpec flg = warnClause_getFlag (e->warn);
10387 if (warnClause_hasMessage (e->warn))
10389 msg = cstring_copy (warnClause_getMessage (e->warn));
10393 msg = message ("Use of possibly dangerous %s",
10394 uentry_ekindNameLC (e));
10398 message ("%q: %q", msg, uentry_getName (e)),
10402 if (sRef_isMacroParamRef (e->sref))
10404 if (uentry_isYield (e) || uentry_isSefParam (e))
10410 if (context_inConditional ())
10414 message ("Macro parameter %q used in conditionally "
10415 "executed code (may or may not be "
10416 "evaluated exactly once)",
10417 uentry_getName (e)),
10420 e->info->var->kind = VKREFSEFPARAM;
10429 message ("Macro parameter %q used more than once",
10430 uentry_getName (e)),
10431 uentry_whereDeclared (e)))
10433 e->info->var->kind = VKREFSEFPARAM;
10440 if ((dp = uentry_directParamNo (e)) >= 0)
10442 uentry_setUsed (usymtab_getParam (dp), loc);
10447 if (!sRef_isLocalVar (e->sref))
10451 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10457 if (context_inMacro ())
10459 e->uses = filelocList_addUndefined (e->uses);
10463 e->uses = filelocList_addDifferentFile
10465 uentry_whereDeclared (e),
10474 bool uentry_isReturned (uentry u)
10476 return (uentry_isValid (u) && uentry_isVar (u)
10477 && (u->info->var->kind == VKRETPARAM
10478 || u->info->var->kind == VKSEFRETPARAM));
10481 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10483 llassert (uentry_isRealFunction (u));
10485 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10487 stateClauseList clauses = uentry_getStateClauseList (u);
10488 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10490 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10491 sRef_setAllocated (res, g_currentloc);
10493 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10494 stateClauseList_unparse (clauses)));
10497 ** This should be in exprNode_reflectEnsuresClause
10500 stateClauseList_postElements (clauses, cl)
10502 if (!stateClause_isGlobal (cl))
10504 sRefSet refs = stateClause_getRefs (cl);
10505 sRefMod modf = stateClause_getEffectFunction (cl);
10507 sRefSet_elements (refs, el)
10509 sRef base = sRef_getRootBase (el);
10511 if (sRef_isResult (base))
10515 sRef sr = sRef_fixBase (el, res);
10516 modf (sr, g_currentloc);
10523 } end_sRefSet_elements ;
10525 } end_stateClauseList_postElements ;
10533 sRefSet prefs = sRefSet_new ();
10534 sRef res = sRef_undefined;
10537 params = uentry_getParams (u);
10539 uentryList_elements (params, current)
10541 if (uentry_isReturned (current))
10543 if (exprNodeList_size (args) >= paramno)
10545 exprNode ecur = exprNodeList_nth (args, paramno);
10546 sRef tref = exprNode_getSref (ecur);
10548 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10550 if (sRef_isValid (tref))
10552 sRef tcref = sRef_copy (tref);
10554 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10556 if (sRef_isDead (tcref))
10558 sRef_setDefined (tcref, g_currentloc);
10559 sRef_setOnly (tcref, g_currentloc);
10562 if (sRef_isRefCounted (tcref))
10564 /* could be a new ref now (but only if its returned) */
10565 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10568 sRef_makeSafe (tcref);
10569 prefs = sRefSet_insert (prefs, tcref);
10575 } end_uentryList_elements ;
10577 if (sRefSet_size (prefs) > 0)
10579 nstate n = sRef_getNullState (u->sref);
10581 if (sRefSet_size (prefs) == 1)
10583 res = sRefSet_choose (prefs);
10587 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10588 res = sRefSet_mergeIntoOne (prefs);
10591 if (nstate_isKnown (n))
10593 sRef_setNullState (res, n, g_currentloc);
10598 if (ctype_isFunction (u->utype))
10600 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10601 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10605 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10608 if (sRef_isRefCounted (res))
10610 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10615 if (sRef_getNullState (res) == NS_ABSNULL)
10617 ctype ct = ctype_realType (u->utype);
10619 if (ctype_isAbstract (ct))
10621 sRef_setNotNull (res, g_currentloc);
10625 if (ctype_isUser (ct))
10627 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10631 sRef_setNotNull (res, g_currentloc);
10636 if (sRef_isRefCounted (res))
10638 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10640 else if (sRef_isKillRef (res))
10642 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10649 ak = sRef_getAliasKind (res);
10651 if (alkind_isImplicit (ak))
10653 sRef_setAliasKind (res,
10654 alkind_fixImplicit (ak),
10658 sRefSet_free (prefs);
10660 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10665 static bool uentry_isRefCounted (uentry ue)
10667 ctype ct = uentry_getType (ue);
10669 if (ctype_isFunction (ct))
10671 return (ctype_isRefCounted (ctype_getReturnType (ct)));
10675 return (ctype_isRefCounted (ct));
10680 ** old was declared yield in the specification.
10681 ** new is declared in the iter implementation.
10684 void uentry_checkYieldParam (uentry old, uentry unew)
10688 llassert (uentry_isVariable (old));
10689 llassert (uentry_isVariable (unew));
10691 unew->info->var->kind = VKYIELDPARAM;
10692 (void) checkTypeConformance (old, unew, TRUE);
10693 checkVarConformance (old, unew, TRUE, FALSE);
10695 /* get rid of param marker */
10697 name = uentry_getName (unew);
10698 cstring_free (unew->uname);
10699 unew->uname = name;
10700 unew->info->var->kind = VKREFYIELDPARAM;
10702 uentry_setUsed (old, fileloc_undefined);
10703 uentry_setUsed (unew, fileloc_undefined);
10706 /*@observer@*/ cstring
10707 uentry_ekindName (uentry ue)
10709 if (uentry_isValid (ue))
10714 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10716 return cstring_makeLiteralTemp ("Datatype");
10718 return cstring_makeLiteralTemp ("Enum member");
10720 return cstring_makeLiteralTemp ("Constant");
10722 if (uentry_isParam (ue))
10724 return cstring_makeLiteralTemp ("Parameter");
10726 else if (uentry_isExpandedMacro (ue))
10728 return cstring_makeLiteralTemp ("Expanded macro");
10732 return cstring_makeLiteralTemp ("Variable");
10735 return cstring_makeLiteralTemp ("Function");
10737 return cstring_makeLiteralTemp ("Iterator");
10739 return cstring_makeLiteralTemp ("Iterator finalizer");
10741 return cstring_makeLiteralTemp ("Struct tag");
10743 return cstring_makeLiteralTemp ("Union tag");
10745 return cstring_makeLiteralTemp ("Enum tag");
10747 return cstring_makeLiteralTemp ("Optional parameters");
10752 return cstring_makeLiteralTemp ("<Undefined>");
10758 /*@observer@*/ cstring
10759 uentry_ekindNameLC (uentry ue)
10761 if (uentry_isValid (ue))
10766 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10768 return cstring_makeLiteralTemp ("datatype");
10770 return cstring_makeLiteralTemp ("enum member");
10772 return cstring_makeLiteralTemp ("constant");
10774 if (uentry_isParam (ue))
10776 return cstring_makeLiteralTemp ("parameter");
10778 else if (uentry_isExpandedMacro (ue))
10780 return cstring_makeLiteralTemp ("expanded macro");
10784 return cstring_makeLiteralTemp ("variable");
10787 return cstring_makeLiteralTemp ("function");
10789 return cstring_makeLiteralTemp ("iterator");
10791 return cstring_makeLiteralTemp ("iterator finalizer");
10793 return cstring_makeLiteralTemp ("struct tag");
10795 return cstring_makeLiteralTemp ("union tag");
10797 return cstring_makeLiteralTemp ("enum tag");
10799 return cstring_makeLiteralTemp ("optional parameters");
10804 return cstring_makeLiteralTemp ("<Undefined>");
10810 void uentry_setHasNameError (uentry ue)
10812 llassert (uentry_isValid (ue));
10814 ue->hasNameError = TRUE;
10817 void uentry_checkName (uentry ue)
10819 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10820 uentry_observeRealName (ue),
10821 bool_unparse (uentry_isVisibleExternally (ue))));
10823 if (uentry_isValid (ue)
10824 && !context_inXHFile ()
10825 && uentry_hasName (ue)
10826 && !uentry_isElipsisMarker (ue)
10827 && context_getFlag (FLG_NAMECHECKS)
10828 && !ue->hasNameError
10829 && !uentry_isEndIter (ue)
10830 && !fileloc_isBuiltin (uentry_whereLast (ue))
10831 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10833 DPRINTF (("Here..."));
10835 if (uentry_isPriv (ue))
10837 ; /* any checks here? */
10839 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10841 ; /* no errors for externals */
10847 if (uentry_isExpandedMacro (ue))
10853 if (uentry_isExpandedMacro (ue))
10857 else if (uentry_isVariable (ue))
10859 sRef sr = uentry_getSref (ue);
10861 if (sRef_isValid (sr))
10863 scope = sRef_getScope (sr);
10870 else if (uentry_isFunction (ue)
10871 || uentry_isIter (ue)
10872 || uentry_isEndIter (ue)
10873 || uentry_isConstant (ue))
10875 scope = uentry_isStatic (ue) ? fileScope : globScope;
10877 else /* datatypes, etc. must be global */
10882 usymtab_checkDistinctName (ue, scope);
10885 if (context_getFlag (FLG_CPPNAMES))
10890 if (scope == globScope)
10892 checkExternalName (ue);
10894 else if (scope == fileScope)
10896 checkFileScopeName (ue);
10900 checkLocalName (ue);
10904 checkAnsiName (ue);
10909 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
10915 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
10918 if (!context_inMacro ())
10920 sRef_setGlobalScopeSafe ();
10923 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
10924 uentry_setUsed (ue, loc);
10926 tloc = fileloc_createExternal ();
10927 uentry_setDefined (ue, tloc);
10928 fileloc_free (tloc);
10929 uentry_setHasNameError (ue);
10931 if (context_getFlag (FLG_REPEATUNRECOG))
10933 uentry_markOwned (ue);
10937 ue = usymtab_supReturnFileEntry (ue);
10940 if (!context_inMacro ())
10942 sRef_clearGlobalScopeSafe ();
10948 uentry uentry_makeGlobalMarker ()
10953 llassert (sRef_inGlobalScope ());
10955 ue = uentry_makeVariableAux
10956 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
10957 sRef_makeGlobalMarker (),
10960 tloc = fileloc_createExternal ();
10961 uentry_setUsed (ue, tloc);
10962 uentry_setDefined (ue, tloc);
10963 fileloc_free (tloc);
10964 uentry_setHasNameError (ue);
10970 bool uentry_isGlobalMarker (uentry ue)
10972 return (uentry_isValid (ue)
10973 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
10978 /* new start modifications */
10985 static void uentry_testInRange (uentry p_e, uentry cconstant) {
10986 if (uentry_isValid(p_e)) {
10987 if (sRef_isValid (p_e->sref)) {
10988 /* char * t = cstring_toCharsSafe (uentry_unparse(cconstant) );
10989 int index = atoi( t );
10992 long index = multiVal_forceInt (uentry_getConstantValue (cconstant));
10993 // usymtab_testInRange (p_e->sref, index);
10999 /* void uentry_setStringLength (uentry p_e, uentry cconstant) { */
11000 /* if( uentry_isValid(p_e) ) { */
11001 /* if( p_e->info != NULL) { */
11002 /* if( p_e->info->var != NULL) { */
11003 /* char *t = cstring_toCharsSafe (uentry_unparse(cconstant)); */
11004 /* int length = atoi( t ); */
11006 /* p_e->info->var->bufinfo->len = length; */
11007 /* p_e->sref->bufinfo.len = length; */
11008 /* printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size); */
11015 static void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
11016 if( uentry_isValid(p_e) ) {
11017 if( p_e->info != NULL) {
11018 if( p_e->info->var != NULL) {
11019 int size = atoi(cstring_toCharsSafe(exprNode_unparse(cconstant) ) );
11020 p_e->info->var->bufinfo->size = size;
11021 p_e->sref->bufinfo.size = size;
11022 printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
11023 // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
11024 // fprintf(stderr, "and %d\n", size );
11034 /* start modifications */
11036 requires: p_e is defined, is a ptr/array variable
11038 effects: sets the state of the variable
11042 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
11043 if( uentry_isValid(p_e) ) {
11044 if( p_e->info != NULL) {
11045 if( p_e->info->var != NULL) {
11046 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11047 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11053 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11057 requires: p_e is defined, is a ptr/array variable
11059 effects: sets the size of the buffer
11062 void uentry_setNullTerminatedState (uentry p_e) {
11063 if( uentry_isValid(p_e) ) {
11064 if( p_e->info != NULL) {
11065 if( p_e->info->var != NULL) {
11066 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11067 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11073 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11078 requires: p_e is defined, is a ptr/array variable
11080 effects: sets the state of the variable
11083 /* void uentry_setNotNullTerminatedState (uentry p_e) { */
11084 /* if( uentry_isValid(p_e) ) { */
11085 /* if( p_e->info != NULL) { */
11086 /* if( p_e->info->var != NULL) { */
11087 /* p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED; */
11088 /* p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED; */
11094 /* fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n"); */
11099 requires: p_e is defined, is a ptr/array variable
11101 effects: sets the size of the buffer
11104 void uentry_setSize (uentry p_e, int size) {
11105 if( uentry_isValid(p_e) ) {
11106 if( p_e->info != NULL) {
11107 if( p_e->info->var != NULL) {
11108 p_e->info->var->bufinfo->size = size;
11109 p_e->sref->bufinfo.size = size;
11115 fprintf(stderr, "uentry:Error in setSize\n");
11120 requires: p_e is defined, is a ptr/array variable
11122 effects: sets the length of the buffer
11125 void uentry_setLen (uentry p_e, int len) {
11126 if( uentry_isValid(p_e) ) {
11127 if( p_e->info != NULL) {
11128 if( p_e->info->var != NULL) {
11129 p_e->info->var->bufinfo->len = len;
11130 p_e->sref->bufinfo.len = len;
11136 fprintf(stderr, "uentry:Error in setLen\n");
11141 bool uentry_hasMetaStateEnsures (uentry e)
11143 if (uentry_isValid (e) && uentry_isFunction (e))
11145 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11153 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11155 llassert (uentry_isValid (e) && uentry_isFunction (e));
11156 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);