2 ** Splint - 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://www.splint.org
28 # include "lclintMacros.nf"
30 # include "structNames.h"
31 # include "nameChecks.h"
33 static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34 static /*@only@*/ fileloc posLoc = fileloc_undefined;
35 static int nuentries = 0;
36 static int totuentries = 0;
38 static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
39 static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
40 static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
41 static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
42 static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
43 static void uentry_checkIterArgs (uentry p_ue);
44 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
46 static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
49 static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
53 static void checkAliasState (/*@notnull@*/ uentry p_old,
54 /*@notnull@*/ uentry p_unew,
55 bool p_mustConform, bool p_completeConform)
56 /*@modifies p_old, p_unew@*/ ;
57 static void checkNullState (/*@notnull@*/ uentry p_old,
58 /*@notnull@*/ uentry p_unew,
59 bool p_mustConform, bool p_completeConform)
60 /*@modifies p_old, p_unew@*/ ;
62 static void checkVarConformance (/*@notnull@*/ uentry p_old,
63 /*@notnull@*/ uentry p_unew,
64 bool p_mustConform, bool p_completeConform)
65 /*@modifies p_old, p_unew@*/;
68 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
69 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
72 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
74 static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
75 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
78 static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
79 static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
80 static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
81 static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
82 static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
84 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
85 ctype p_oldType, /*@notnull@*/ uentry p_unew,
86 /*@notnull@*/ uentry p_newCurrent,
87 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
89 static /*@only@*/ /*@notnull@*/ uentry
90 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
91 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
93 static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
95 if (uentry_isVariable (ue)
96 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
97 || ctype_isUnknown (uentry_getType (ue))))
99 uentry_makeVarFunction (ue);
103 static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
105 uentry ue = (uentry) dmalloc (sizeof (*ue));
106 ue->warn = warnClause_undefined; /*@i32@*/
113 static cstring uentry_getOptName (uentry p_e) /*@*/ ;
114 static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
116 static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
117 static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
118 static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
119 static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
120 static void ucinfo_free (/*@only@*/ ucinfo p_u);
121 static void uvinfo_free (/*@only@*/ uvinfo p_u);
125 static /*@only@*/ cstring ancontext_unparse (ancontext an)
129 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
130 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
131 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
132 case AN_SUFIELD: return cstring_makeLiteral ("su field");
133 case AN_TDEFN: return cstring_makeLiteral ("type definition");
134 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
135 case AN_CONST: return cstring_makeLiteral ("constant");
141 static int annots[AN_LAST][QU_LAST];
142 static int decls[AN_LAST];
143 static int shdecls[AN_LAST];
144 static int idecls[AN_LAST];
150 for (i = AN_UNKNOWN; i < AN_LAST; i++)
156 for (j = QU_UNKNOWN; j < QU_LAST; j++)
163 static void tallyAnnot (ancontext ac, qual q)
177 for (j = QU_UNKNOWN; j < QU_LAST; j++)
182 for (i = AN_UNKNOWN; i < AN_LAST; i++)
188 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
189 ancontext_unparse (i),
190 decls[i], shdecls[i], idecls[i]);
192 totdecls += decls[i];
193 totshdecls += shdecls[i];
194 totidecls += idecls[i];
196 for (j = QU_UNKNOWN; j < QU_LAST; j++)
198 total[j] += annots[i][j];
199 alltotals += annots[i][j];
202 printf (" Allocation:\n");
206 for (j = QU_UNKNOWN; j < QU_LAST; j++)
208 if (qual_isAliasQual (j) && !qual_isUnique (j))
210 if (annots[i][j] > 0)
212 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
213 100.0 * (double)annots[i][j] / (double)decls[i]);
214 tmptot += annots[i][j];
219 printf (" Exposure:\n");
223 for (j = QU_UNKNOWN; j < QU_LAST; j++)
225 if (qual_isExQual (j))
227 if (annots[i][j] > 0)
229 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
230 100.0 * (double)annots[i][j] / (double)decls[i]);
231 tmptot += annots[i][j];
236 printf (" Definition:\n");
238 for (j = QU_UNKNOWN; j < QU_LAST; j++)
240 if (qual_isAllocQual (j))
242 if (annots[i][j] > 0)
244 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
245 100.0 * (double)annots[i][j] / (double)decls[i]);
252 for (j = QU_UNKNOWN; j < QU_LAST; j++)
254 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
256 if (annots[i][j] > 0)
258 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
259 100.0 * (double)annots[i][j] / (double)decls[i]);
268 for (j = QU_UNKNOWN; j < QU_LAST; j++)
272 for (i = AN_UNKNOWN; i < AN_LAST; i++)
274 if (annots[i][j] > 0)
283 printf ("Annotation: %s\n", qual_unparse (j));
285 for (i = AN_UNKNOWN; i < AN_LAST; i++)
287 if (annots[i][j] > 0)
289 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
296 printf ("All Contexts\n");
298 for (j = QU_UNKNOWN; j < QU_LAST; j++)
302 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
303 100.0 * (double)total[j] / (double)(totdecls));
308 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
310 extern void uentry_tallyAnnots (uentry u, ancontext kind)
312 alkind ak = sRef_getAliasKind (u->sref);
313 exkind ek = sRef_getExKind (u->sref);
314 nstate ns = sRef_getNullState (u->sref);
315 sstate ss = sRef_getDefState (u->sref);
316 bool recordUnknown = FALSE;
318 if (kind == AN_UNKNOWN)
326 else if (e == KCONST || e == KENUMCONST)
330 else if (e == KFCN || e == KITER)
332 uentryList params = uentry_getParams (u);
335 uentryList_elements (params, current)
337 if (uentry_isReturned (current))
341 if (!uentry_isElipsisMarker (current))
343 uentry_tallyAnnots (current, AN_FCNPARAM);
345 } end_uentryList_elements;
349 if (ctype_isFunction (u->utype)
351 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
353 recordUnknown = TRUE;
356 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
358 ctype t = ctype_realType (u->utype);
362 uentryList fields = ctype_getFields (t);
364 uentryList_elements (fields, current)
366 uentry_tallyAnnots (current, AN_SUFIELD);
368 } end_uentryList_elements;
372 if (ctype_isVisiblySharable (u->utype))
374 recordUnknown = TRUE;
382 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
384 recordUnknown = TRUE;
391 if (kind == AN_FCNRETURN)
405 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
410 if (ctype_isRealPointer (ctype_realType (u->utype)))
418 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
419 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
420 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
421 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
425 if (uentry_isReturned (u))
427 tallyAnnot (kind, QU_RETURNED);
433 if (ctype_isRefCounted (ctype_realType (u->utype))
434 || (ctype_isFunction (u->utype) &&
435 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
441 if (kind == AN_FCNPARAM)
443 tallyAnnot (kind, QU_TEMP);
445 else if (recordUnknown)
447 if (kind == AN_FCNRETURN)
450 tallyAnnot (kind, QU_UNKNOWN);
454 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
455 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
456 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
457 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
459 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
460 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
461 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
462 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
463 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
464 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
465 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
466 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
467 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
468 case AK_IMPDEPENDENT:
469 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
479 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
480 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
486 case NS_ERROR: break;
487 case NS_UNKNOWN: break;
488 case NS_NOTNULL: break;
489 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
490 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
491 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
492 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
494 case NS_ABSNULL: break;
500 static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
504 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
505 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
506 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
507 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
508 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
514 static specCode specCode_fromInt (int i)
517 llassert (i >= SPC_NONE && i < SPC_LAST);
519 return ((specCode) i);
523 /*@observer@*/ cstring uentry_specOrDefName (uentry u)
525 if (uentry_isDeclared (u))
527 return cstring_makeLiteralTemp ("previously declared");
531 return cstring_makeLiteralTemp ("specified");
535 /*@observer@*/ cstring uentry_specDeclName (uentry u)
537 if (uentry_isDeclared (u))
539 return cstring_makeLiteralTemp ("previous declaration");
543 return cstring_makeLiteralTemp ("specification");
547 static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
549 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
551 return cstring_makeLiteralTemp ("redefined");
553 else if (uentry_isCodeDefined (unew))
555 return cstring_makeLiteralTemp ("defined");
557 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
559 return cstring_makeLiteralTemp ("redeclared");
563 return cstring_makeLiteralTemp ("declared");
567 static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
569 if (uentry_isValid (ue))
571 functionConstraint constraint;
573 DPRINTF( (message ("called uentry_getFcnPostconditions on %s",
574 uentry_unparse (ue) ) ) );
576 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
578 DPRINTF( (message ("called uentry_getFunctionConditions on nonfunction %s",
579 uentry_unparse (ue) ) ) );
580 if (!uentry_isFunction (ue) )
582 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
583 uentry_unparse (ue) ) ));
584 return constraintList_undefined;
588 return constraintList_undefined;
591 if (!uentry_isFunction(ue))
594 DPRINTF( (message ("called uentry_getFunctionConditions on non function %s",
595 uentry_unparse (ue) ) ) );
596 return constraintList_undefined;
600 llassert (uentry_isFunction (ue));
604 constraint = ue->info->fcn->postconditions;
608 constraint = ue->info->fcn->preconditions;
611 return functionConstraint_getBufferConstraints (constraint);
614 return constraintList_undefined;
619 /*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
621 return uentry_getFunctionConditions (ue, FALSE);
628 constraintList uentry_getFcnPostconditions (uentry ue)
630 return uentry_getFunctionConditions (ue, TRUE);
633 static /*@only@*/ fileloc setLocation (void)
635 fileloc fl = context_getSaveLocation ();
637 if (fileloc_isDefined (fl))
643 return fileloc_copy (g_currentloc);
647 static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
649 llassert (uentry_isEitherConstant (ue));
650 sRef_setValue (ue->sref, val);
653 /*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
655 fileloc loc = setLocation ();
656 uentry ue = uentry_makeConstant (n, t, loc);
658 ue->ukind = KENUMCONST;
659 uentry_setDefined (ue, loc);
663 /*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
665 fileloc loc = setLocation ();
666 uentry ue = uentry_makeConstant (n, t, loc);
667 ctype etype = exprNode_getType (expr);
669 if (!ctype_isRealInt (etype)) {
673 ("Value of enum member is not an integeral type (type %s): %s",
674 ctype_unparse (etype), exprNode_unparse (expr)),
675 exprNode_loc (expr));
678 ue->ukind = KENUMCONST;
679 uentry_setDefined (ue, loc);
684 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
686 uentry ue = uentry_makeConstant (n, t, loc);
688 ue->ukind = KENUMCONST;
693 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
695 return uentry_makeVariable (n, t, setLocation (), FALSE);
699 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
701 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
705 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
707 ctype ct = idDecl_getCtype (id);
708 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
709 MAYBE, MAYBE, setLocation ());
711 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
713 if (!ynm_isOn (ue->info->datatype->abs))
715 if (ctype_isUnknown (ct))
717 ue->info->datatype->mut = MAYBE;
721 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
728 void uentry_checkParams (uentry ue)
730 if (uentry_isValid (ue))
732 bool isExt = uentry_isExtern (ue);
734 if (uentry_isRealFunction (ue))
736 uentryList params = uentry_getParams (ue);
738 uentryList_elements (params, current)
740 if (uentry_isValid (current))
742 ctype ct = current->utype;
744 if (ctype_isFixedArray (ct))
746 if (ctype_isArray (ctype_baseArrayPtr (ct))
747 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
754 (FLG_FIXEDFORMALARRAY,
755 message ("Function parameter %q declared as "
756 "manifest array (size constant is meaningless)",
757 uentry_getName (current)),
758 uentry_whereDeclared (current));
763 if (ctype_isArray (ct))
767 message ("Function parameter %q declared as "
768 "array (treated as pointer)",
769 uentry_getName (current)),
770 uentry_whereDeclared (current));
774 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
776 if (ctype_isAbstract (ct) &&
777 (isExt || (ctype_isAbstract (ctype_realType (ct))
778 && !context_hasFileAccess (ctype_typeId (ct)))))
783 ("Function %q declared with notnull parameter %q of abstract "
786 uentry_getName (current),
789 ("Since %s is an abstract type, notnull can only be "
790 "used for parameters if the function is static to a "
791 "module where %s is accessible.",
794 uentry_whereDeclared (current));
798 } end_uentryList_elements;
800 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
802 ctype ct = ue->utype;
804 if (ctype_isAbstract (ct)
805 && (isExt || (ctype_isAbstract (ctype_realType (ct))
806 && !context_hasFileAccess (ctype_typeId (ct)))))
811 ("%s %q declared %s notnull storage of abstract type %s",
812 ekind_capName (uentry_getKind (ue)),
817 ("Since %s is an abstract type, notnull can only be used "
818 "if it is static to a module where %s is accessible.",
821 uentry_whereDeclared (ue));
828 static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
830 alkind ak = sRef_getAliasKind (ue->sref);
832 if (alkind_isRefCounted (ak))
834 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
838 if (alkind_isUnknown (ak))
840 exkind ek = sRef_getExKind (ue->sref);
842 if (exkind_isKnown (ek))
844 DPRINTF (("Setting imp dependent: %s",
845 uentry_unparseFull (ue)));
846 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
850 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
852 /* evans 2000-12-22 removed ctype_realType so it will
853 not apply to immutable abstract types. */
855 if (ctype_isVisiblySharable
856 (ctype_realType (ctype_getReturnType (ue->utype))))
858 if (uentryList_hasReturned (uentry_getParams (ue)))
864 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
866 ; /* Immutable objects are not shared. */
870 sRef_setAliasKind (ue->sref, AK_IMPONLY,
872 DPRINTF (("Ret imp only: %s",
873 ctype_unparse (ctype_getReturnType (ue->utype))));
883 static /*@notnull@*/ uentry
884 uentry_makeFunctionAux (cstring n, ctype t,
886 /*@only@*/ globSet globs,
887 /*@only@*/ sRefSet mods,
888 /*@only@*/ warnClause warn,
889 /*@keep@*/ fileloc f, bool priv,
890 /*@unused@*/ bool isForward)
892 uentry e = uentry_alloc ();
895 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
897 DPRINTF (("Make function: %s", n));
899 if (ctype_isFunction (t))
901 ret = ctype_getReturnType (t);
905 if (ctype_isKnown (t))
907 llbug (message ("not function: %s", ctype_unparse (t)));
914 if (fileloc_isSpec (f) || fileloc_isImport (f))
916 e->whereSpecified = f;
917 e->whereDeclared = fileloc_undefined;
921 e->whereSpecified = fileloc_undefined;
922 e->whereDeclared = f;
925 /* e->shallowCopy = FALSE; */
926 e->uname = cstring_copy (n);
928 e->storageclass = SCNONE;
930 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
932 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
934 if (ctype_isUA (ret))
936 sRef_setStateFromType (e->sref, ret);
941 e->uses = filelocList_new ();
943 e->hasNameError = FALSE;
947 e->info = (uinfo) dmalloc (sizeof (*e->info));
948 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
950 e->info->fcn->hasMods = sRefSet_isDefined (mods);
951 e->info->fcn->hasGlobs = globSet_isDefined (globs);
953 e->info->fcn->exitCode = XK_UNKNOWN;
954 e->info->fcn->nullPred = qual_createUnknown ();
955 e->info->fcn->specialCode = SPC_NONE;
957 e->info->fcn->access = access;
958 e->info->fcn->globs = globs;
959 e->info->fcn->defparams = uentryList_undefined;
961 sRef_setDefined (e->sref, f);
962 e->whereDefined = fileloc_undefined;
964 e->info->fcn->mods = sRefSet_undefined;
965 e->info->fcn->specclauses = NULL;
968 e->info->fcn->preconditions = NULL;
972 e->info->fcn->postconditions = NULL;
975 checkGlobalsModifies (e, mods);
976 e->info->fcn->mods = mods;
981 static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
983 functionClauseList_elements (clauses, el)
985 DPRINTF (("Reflect clause: %s on %s",
986 functionClause_unparse (el), uentry_getName (ue)));
988 if (functionClause_isNoMods (el))
990 modifiesClause mel = functionClause_getModifies (el);
992 if (uentry_hasGlobs (ue))
997 ("No globals and modifies inconsistent to globals clause for %q: %q",
999 globSet_unparse (uentry_getGlobs (ue))),
1000 modifiesClause_getLoc (mel));
1004 if (uentry_hasMods (ue))
1009 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1010 uentry_getName (ue),
1011 sRefSet_unparse (uentry_getMods (ue))),
1012 modifiesClause_getLoc (mel));
1015 uentry_setGlobals (ue, globSet_undefined);
1016 uentry_setModifies (ue, sRefSet_undefined);
1018 else if (functionClause_isGlobals (el))
1020 globalsClause glc = functionClause_getGlobals (el);
1022 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1023 globalsClause_unparse (glc)));
1025 if (uentry_hasGlobs (ue))
1030 ("Multiple globals clauses for %q: %q",
1031 uentry_getName (ue),
1032 globalsClause_unparse (glc)),
1033 globalsClause_getLoc (glc));
1034 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1038 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
1041 else if (functionClause_isModifies (el))
1043 modifiesClause mlc = functionClause_getModifies (el);
1045 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1047 if (uentry_hasMods (ue))
1055 ("Multiple modifies clauses for %s: %s",
1056 uentry_getName (ue),
1057 modifiesClause_unparse (mlc)),
1058 modifiesClause_getLoc (mlc)))
1060 llhint (message ("Previous modifies clause: ",
1061 sRefSet_unparse (uentry_getMods (ue))));
1067 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1071 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1074 else if (functionClause_isEnsures (el))
1076 functionConstraint cl = functionClause_takeEnsures (el);
1077 DPRINTF (("Setting post: %s / %s",
1078 uentry_unparse (ue), functionConstraint_unparse (cl)));
1079 uentry_setPostconditions (ue, cl);
1081 else if (functionClause_isRequires (el))
1083 functionConstraint cl = functionClause_takeRequires (el);
1084 uentry_setPreconditions (ue, cl);
1086 else if (functionClause_isState (el))
1088 stateClause sc = functionClause_takeState (el);
1090 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1092 sRefSet rfs = stateClause_getRefs (sc);
1094 sRefSet_elements (rfs, s)
1096 if (sRef_isParam (s))
1099 ** Can't use requires on parameters
1103 (FLG_ANNOTATIONERROR,
1104 message ("Requires clauses for %q concerns parameters %q should be "
1105 "a parameter annotation instead: %q",
1106 uentry_unparse (ue),
1108 stateClause_unparse (sc)),
1109 stateClause_loc (sc));
1111 } end_sRefSet_elements ;
1114 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
1115 uentry_addStateClause (ue, sc);
1117 else if (functionClause_isWarn (el))
1119 warnClause wc = functionClause_takeWarn (el);
1120 uentry_addWarning (ue, wc);
1124 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1126 } end_functionClauseList_elements ;
1128 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
1129 stateClauseList_checkAll (ue);
1132 /*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1134 bool leaveFunc = FALSE;
1136 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1137 typeId_invalid, globSet_undefined,
1138 sRefSet_undefined, warnClause_undefined,
1141 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1144 ** This makes parameters names print out correctly.
1145 ** (But we might be a local variable declaration for a function type...)
1148 if (context_inFunctionLike ())
1150 DPRINTF (("Header: %s / %s",
1151 uentry_unparse (context_getHeader ()),
1152 idDecl_unparse (id)));
1156 context_enterFunctionDeclaration (ue);
1160 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1161 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
1162 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1163 reflectImplicitFunctionQualifiers (ue, FALSE);
1164 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1165 uentry_reflectClauses (ue, idDecl_getClauses (id));
1166 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1168 if (!uentry_isStatic (ue)
1169 && cstring_equalLit (ue->uname, "main"))
1171 ctype typ = ue->utype;
1175 llassert (ctype_isFunction (typ));
1177 retval = ctype_getReturnType (typ);
1179 if (!ctype_isInt (retval))
1183 message ("Function main declared to return %s, should return int",
1184 ctype_unparse (retval)),
1185 uentry_whereDeclared (ue));
1188 args = ctype_argsFunction (typ);
1190 if (uentryList_isMissingParams (args)
1191 || uentryList_size (args) == 0)
1197 if (uentryList_size (args) != 2)
1201 message ("Function main declared with %d arg%&, "
1202 "should have 2 (int argc, char *argv[])",
1203 uentryList_size (args)),
1204 uentry_whereLast (ue));
1208 uentry arg = uentryList_getN (args, 0);
1209 ctype ct = uentry_getType (arg);
1211 if (!ctype_isInt (ct))
1215 message ("Parameter 1, %q, of function main declared "
1216 "with type %t, should have type int",
1217 uentry_getName (arg), ct),
1218 uentry_whereDeclared (arg));
1221 arg = uentryList_getN (args, 1);
1222 ct = uentry_getType (arg);
1224 if (ctype_isArrayPtr (ct)
1225 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1226 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1234 message ("Parameter 2, %q, of function main declared "
1235 "with type %t, should have type char **",
1236 uentry_getName (arg), ct),
1237 uentry_whereDeclared (arg));
1245 context_exitFunctionDeclaration ();
1251 static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1253 alkind ak = sRef_getAliasKind (e->sref);
1255 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1256 && context_getFlag (FLG_PARAMIMPTEMP))
1258 exkind ek = sRef_getExKind (e->sref);
1260 if (exkind_isKnown (ek))
1262 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
1263 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1264 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1268 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1269 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1274 static /*@only@*/ /*@notnull@*/ uentry
1275 uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1276 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
1278 cstring pname = makeParam (n);
1281 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
1282 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
1284 cstring_free (pname);
1285 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1286 uentry_implicitParamAnnots (e);
1287 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1289 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1291 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1292 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1293 e->info->var->defstate = defstate;
1296 DPRINTF (("Param: %s", uentry_unparseFull (e)));
1302 uentry_setRefCounted (uentry e)
1304 if (uentry_isValid (e))
1306 uentry_setAliasKind (e, AK_REFCOUNTED);
1307 sRef_storeState (e->sref);
1313 uentry_setStatic (uentry c)
1315 if (uentry_isValid (c))
1317 alkind ak = sRef_getAliasKind (c->sref);
1318 c->storageclass = SCSTATIC;
1320 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1322 if (!alkind_isUnknown (ak)
1323 && !alkind_isStatic (ak))
1325 if (!(ctype_isRealPointer (uentry_getType (c)))
1326 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1327 && !alkind_isRefCounted (ak))
1329 if (alkind_isImplicit (ak)
1330 && alkind_isDependent (ak)
1331 && ctype_isArray (uentry_getType (c)))
1333 ; /* no error for observer arrays */
1339 message ("Static storage %q declared as %s",
1341 alkind_unparse (ak)),
1342 uentry_whereDeclared (c));
1348 if (alkind_isUnknown (ak)
1349 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1350 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1352 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1353 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1361 uentry_setExtern (uentry c)
1363 if (uentry_isValid (c))
1364 c->storageclass = SCEXTERN;
1368 uentry_setParamNo (uentry ue, int pno)
1370 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1371 sRef_setParamNo (ue->sref, pno);
1375 void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1377 sRefSet_allElements (sr, el)
1379 sRef base = sRef_getRootBase (el);
1381 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
1382 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1384 if (!globSet_member (ue->info->fcn->globs, base))
1386 if (uentry_hasGlobs (ue)
1387 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1390 (FLG_WARNMISSINGGLOBALS,
1392 ("Modifies list for %q uses global %q, "
1393 "not included in globals list.",
1394 uentry_getName (ue),
1395 sRef_unparse (base)),
1396 uentry_whereLast (ue)))
1398 uentry_showWhereSpecified (ue);
1402 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1404 if (sRef_isFileStatic (base))
1406 context_recordFileGlobals (ue->info->fcn->globs);
1410 } end_sRefSet_allElements;
1414 uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
1416 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
1420 uentry_fixupSref (uentry ue)
1424 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1429 sr = uentry_getSref (ue);
1431 sRef_resetState (sr);
1432 sRef_clearDerived (sr);
1434 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1435 llassert (sRef_isValid (sr));
1437 if (uentry_isVariable (ue))
1439 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
1440 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1441 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1445 static void uentry_addStateClause (uentry ue, stateClause sc)
1448 ** Okay to allow multiple clauses of the same kind.
1449 */ /*@i834 is this true?@*/
1451 ue->info->fcn->specclauses =
1452 stateClauseList_add (ue->info->fcn->specclauses, sc);
1454 /* Will call checkAll to check later... */
1457 void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
1459 llassert (uentry_isFunction (ue));
1460 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
1462 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
1463 ue->info->fcn->specclauses = clauses;
1464 stateClauseList_checkAll (ue);
1465 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
1469 ** Used for @modifies@ @endmodifies@ syntax.
1471 ** If ue is specified, sr must contain *only*:
1473 ** o file static globals
1474 ** o sRef's derived from modifies spec (i.e., more specific than
1475 ** what was specified)
1477 ** Otherwise, if sr has modifies it must match sr.
1479 ** If it doesn't have modifies, set them to sr.
1483 uentry_checkModifiesContext (void)
1485 if (sRef_modInFunction ())
1489 ("Modifies list not in function context. "
1490 "A modifies list can only appear following the parameter list "
1491 "in a function declaration or header."));
1500 uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1502 if (!uentry_checkModifiesContext ())
1508 if (uentry_isValid (ue))
1510 if (uentry_isIter (ue))
1512 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1513 ue->info->iter->mods = sr;
1517 uentry_convertVarFunction (ue);
1518 llassertfatal (uentry_isFunction (ue));
1519 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1521 ue->info->fcn->mods = sr;
1522 ue->info->fcn->hasMods = TRUE;
1524 checkGlobalsModifies (ue, sr);
1527 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1529 ue->info->fcn->hasGlobs = TRUE;
1532 if (sRefSet_hasStatic (ue->info->fcn->mods))
1534 context_recordFileModifies (ue->info->fcn->mods);
1544 uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1547 ** Function already has one modifies clause (possibly from
1548 ** a specification).
1551 if (!uentry_checkModifiesContext ())
1556 llassert (uentry_isValid (ue));
1558 if (uentry_isIter (ue))
1560 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1564 llassertfatal (uentry_isFunction (ue));
1565 llassert (ue->info->fcn->hasMods);
1567 checkGlobalsModifies (ue, sr);
1568 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1570 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1572 ue->info->fcn->hasGlobs = TRUE;
1576 if (sRefSet_hasStatic (ue->info->fcn->mods))
1578 context_recordFileModifies (ue->info->fcn->mods);
1582 bool uentry_hasWarning (uentry ue)
1584 return (uentry_isValid (ue)
1585 && warnClause_isDefined (ue->warn));
1588 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1590 llassert (warnClause_isUndefined (ue->warn));
1595 uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
1597 if (sRef_modInFunction ())
1600 (message ("Precondition list not in function context. "
1601 "A precondition list can only appear following the parameter list "
1602 "in a function declaration or header."));
1604 /*@-mustfree@*/ return; /*@=mustfree@*/
1607 if (uentry_isValid (ue))
1609 uentry_convertVarFunction (ue);
1610 llassertfatal (uentry_isFunction (ue));
1612 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1615 I changed this so it didn't appear as a Splint bug
1616 among other things this gets triggered when there is
1617 a function with two requires clauses. Now Splint
1618 prints an error and tries to conjoin the lists.
1621 (message ("Duplicate precondition list"
1622 "Attemping the conjoin the requires clauses"
1626 /* should conjoin constraints? */
1628 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1632 ue->info->fcn->preconditions = preconditions;
1637 llfatalbug ( (message("uentry_setPreconditions called with invalid uentry") ));
1646 uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
1648 if (sRef_modInFunction ())
1651 (message ("Postcondition list not in function context. "
1652 "A postcondition list can only appear following the parameter list "
1653 "in a function declaration or header."));
1655 /*@-mustfree@*/ return; /*@=mustfree@*/
1658 if (uentry_isValid (ue))
1660 uentry_convertVarFunction (ue);
1661 llassertfatal (uentry_isFunction (ue));
1663 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1665 ue->info->fcn->postconditions = postconditions;
1669 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1674 llfatalbug ( (message("uentry_setPostconditions called with invalid uentry") ));
1679 ** requires: new and old are functions
1683 checkGlobalsConformance (/*@notnull@*/ uentry old,
1684 /*@notnull@*/ uentry unew,
1685 bool mustConform, bool completeConform)
1687 bool hasInternalState = FALSE;
1689 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1691 if (globSet_isDefined (unew->info->fcn->globs))
1693 globSet_allElements (unew->info->fcn->globs, el)
1695 if (sRef_isFileStatic (el))
1697 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1699 if (sRef_isInvalid (sr))
1701 bool hasError = FALSE;
1703 if (!hasInternalState
1704 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1705 sRef_makeInternalState ()))
1706 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1707 sRef_makeSpecState ())))
1710 && !uentry_isStatic (old)
1713 message ("Globals list for %q includes internal state, %q, "
1714 "but %s without globals internalState.",
1715 uentry_getName (old),
1717 uentry_specOrDefName (old)),
1718 uentry_whereLast (unew)))
1720 uentry_showWhereSpecified (old);
1724 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1725 sRef_makeInternalState ());
1726 hasInternalState = TRUE;
1730 && fileloc_sameFile (uentry_whereDeclared (unew),
1731 uentry_whereDeclared (old)))
1736 message ("Function %q inconsistently %rdeclared (in "
1737 "same file) with file static global %q in "
1739 uentry_getName (unew),
1740 uentry_isDeclared (old),
1742 uentry_whereDeclared (unew)))
1744 uentry_showWhereSpecified (old);
1749 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1750 context_recordFileGlobals (old->info->fcn->globs);
1754 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1756 if (sRef_isInvalid (sr))
1761 message ("Function %q inconsistently %rdeclared with "
1762 "%q in globals list",
1763 uentry_getName (unew),
1764 uentry_isDeclared (old),
1766 uentry_whereDeclared (unew)))
1768 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1769 uentry_showWhereSpecified (old);
1774 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1780 ("Function %q global %q inconsistently "
1781 "%rdeclared as %qout global",
1782 uentry_getName (unew),
1784 uentry_isDeclared (old),
1785 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1786 uentry_whereDeclared (unew)))
1788 uentry_showWhereSpecified (old);
1793 } end_globSet_allElements ;
1795 if (completeConform)
1797 globSet_allElements (old->info->fcn->globs, el)
1799 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1801 if (sRef_isInvalid (sr))
1804 && uentry_isReallySpecified (old)
1807 message ("Function %q specified with %q in globals list, "
1808 "but declared without %q",
1809 uentry_getName (unew),
1812 uentry_whereDeclared (unew)))
1814 uentry_showWhereSpecified (old);
1817 } end_globSet_allElements;
1822 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1824 if (uentry_isReallySpecified (old)
1827 message ("%s %q specified with globals list, but "
1828 "declared with no globals",
1829 ekind_capName (unew->ukind),
1830 uentry_getName (unew)),
1831 uentry_whereDeclared (unew)))
1834 (message ("Specification globals: %q",
1835 globSet_unparse (old->info->fcn->globs)),
1836 uentry_whereSpecified (old));
1840 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1841 old->info->fcn->globs);
1846 ** new modifies list must be included by old modifies list.
1848 ** file static state may be added to new, if old has internal.
1852 checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1853 bool mustConform, bool completeConform)
1856 bool changedMods = FALSE;
1857 bool modInternal = FALSE;
1859 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1861 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1862 newMods = unew->info->fcn->mods;
1864 if (sRefSet_isEmpty (newMods))
1866 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1867 && uentry_isReallySpecified (old))
1871 message ("%s %q specified with modifies clause, "
1872 "but declared with no modifies clause",
1873 ekind_capName (unew->ukind),
1874 uentry_getName (unew)),
1875 uentry_whereDeclared (unew)))
1877 llgenindentmsg (message ("Specification has modifies %q",
1878 sRefSet_unparse (old->info->fcn->mods)),
1879 uentry_whereSpecified (old));
1886 sRefSet_allElements (newMods, current)
1888 if (sRef_isValid (current))
1890 sRef rb = sRef_getRootBase (current);
1892 if (sRef_isFileStatic (rb))
1896 if (!sRefSet_isSameMember (old->info->fcn->mods,
1897 sRef_makeInternalState ())
1898 && !sRefSet_isSameMember (old->info->fcn->mods,
1899 sRef_makeSpecState ()))
1902 && !uentry_isStatic (old)
1906 ("Modifies list for %q includes internal state, "
1907 "but %s without modifies internal.",
1908 uentry_getName (old),
1909 uentry_specOrDefName (old)),
1910 uentry_whereLast (unew)))
1912 uentry_showWhereSpecified (old);
1915 old->info->fcn->mods =
1916 sRefSet_insert (old->info->fcn->mods,
1917 sRef_makeInternalState ());
1922 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1928 if (sRef_canModifyVal (current, old->info->fcn->mods))
1930 int size = sRefSet_size (old->info->fcn->mods);
1932 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1935 if (sRefSet_size (old->info->fcn->mods) != size)
1946 ("Modifies list for %q contains %q, not modifiable "
1948 uentry_getName (old),
1949 sRef_unparse (current),
1950 uentry_specDeclName (old)),
1951 uentry_whereLast (unew)))
1953 uentry_showWhereSpecified (old);
1958 } end_sRefSet_allElements;
1960 if (completeConform && uentry_isReallySpecified (old))
1962 sRefSet_allElements (old->info->fcn->mods, el)
1964 if (sRef_canModify (el, newMods))
1973 ("Specification modifies clause for %q contains %q, "
1974 "not included in declaration modifies clause",
1975 uentry_getName (old),
1977 uentry_whereLast (unew)))
1979 uentry_showWhereSpecified (old);
1982 } end_sRefSet_allElements ;
1986 ** Make sure file static elements will be removed.
1991 context_recordFileModifies (old->info->fcn->mods);
1996 uentry_checkMutableType (uentry ue)
1998 ctype ct = uentry_getType (ue);
2000 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2002 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2004 voptgenerror (FLG_MUTREP,
2005 message ("Mutable abstract type %q declared without pointer "
2006 "indirection: %t (violates assignment semantics)",
2007 uentry_getName (ue), ct),
2008 uentry_whereDeclared (ue));
2013 uentry_setMutable (uentry e)
2015 llassert (uentry_isDatatype (e));
2016 e->info->datatype->mut = YES;
2020 uentry_checkIterArgs (uentry ue)
2022 bool hasYield = FALSE;
2025 llassert (uentry_isIter (ue));
2027 args = uentry_getParams (ue);
2029 uentryList_elements (args, el)
2031 sstate ds = uentry_getDefState (el);
2033 if (uentry_isYield (el))
2038 if (sstate_isUnknown (ds))
2040 uentry_setDefState (el, SS_DEFINED);
2046 } end_uentryList_elements;
2050 voptgenerror (FLG_HASYIELD,
2051 message ("Iterator %q declared with no yield parameters",
2052 uentry_getName (ue)),
2053 uentry_whereDeclared (ue));
2058 chkind_fromQual (qual qel)
2060 if (qual_isChecked (qel))
2064 else if (qual_isCheckMod (qel))
2068 else if (qual_isCheckedStrict (qel))
2070 return CH_CHECKEDSTRICT;
2072 else if (qual_isUnchecked (qel))
2074 return CH_UNCHECKED;
2079 /*@notreached@*/ return CH_UNKNOWN;
2084 uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2086 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2088 if (!uentry_isRefCounted (ue))
2091 (FLG_ANNOTATIONERROR,
2092 message ("Reference counting qualifier %s used on non-reference "
2093 "counted storage: %q",
2095 uentry_unparse (ue)),
2096 uentry_whereLast (ue));
2100 alkind ak = alkind_fromQual (qel);
2102 uentry_setAliasKind (ue, ak);
2105 else if (qual_isRefCounted (qel))
2107 ctype ct = ctype_realType (uentry_getType (ue));
2110 if (ctype_isPointer (ct)
2111 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2113 /* check there is a refs field */
2114 uentryList fields = ctype_getFields (rt);
2115 uentry refs = uentry_undefined;
2117 uentryList_elements (fields, field)
2119 if (uentry_isRefsField (field))
2121 if (uentry_isValid (refs))
2124 (FLG_ANNOTATIONERROR,
2125 message ("Reference counted structure type %s has "
2126 "multiple refs fields: %q and %q",
2128 uentry_getName (refs),
2129 uentry_getName (field)),
2130 uentry_whereLast (field));
2135 } end_uentryList_elements;
2137 if (uentry_isInvalid (refs))
2141 message ("Reference counted structure type %s has "
2143 ctype_unparse (ct)),
2145 ("To count reference, the structure must have a field named "
2146 "refs of type int."),
2149 else if (!ctype_isInt (uentry_getType (refs)))
2152 (FLG_ANNOTATIONERROR,
2153 message ("Reference counted structure type %s refs field has "
2154 "type %s (should be int)", ctype_unparse (ct),
2155 ctype_unparse (uentry_getType (refs))),
2156 uentry_whereLast (refs));
2160 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2161 uentry_whereDeclared (ue));
2166 if ((ctype_isPointer (ct)
2167 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2168 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2170 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2171 uentry_whereDeclared (ue));
2176 (FLG_ANNOTATIONERROR,
2177 message ("Non-pointer to structure type %s declared with "
2178 "refcounted qualifier",
2179 ctype_unparse (ct)),
2180 uentry_whereLast (ue));
2184 else if (qual_isRefs (qel))
2186 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2188 uentry_setAliasKind (ue, AK_REFS);
2193 (FLG_ANNOTATIONERROR,
2194 message ("Refs qualifier used on non-structure field: %q",
2195 uentry_unparse (ue)),
2196 uentry_whereLast (ue));
2199 else if (qual_isAliasQual (qel))
2201 alkind ak = alkind_fromQual (qel);
2203 alkind oldak = uentry_getAliasKind (ue);
2204 ctype ut = uentry_getType (ue);
2206 if (alkind_isImplicit (ak)
2207 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2209 /* ignore the implied qualifier */
2213 if (uentry_isEitherConstant (ue))
2216 (FLG_ANNOTATIONERROR,
2217 message ("Alias qualifier %s used on constant: %q",
2218 alkind_unparse (ak), uentry_unparse (ue)),
2219 uentry_whereLast (ue));
2224 if (ctype_isFunction (ut))
2226 ut = ctype_getReturnType (ut);
2229 if (!(ctype_isVisiblySharable (ut)
2230 || ctype_isRealArray (ut)
2231 || ctype_isRealSU (ut)))
2233 if (!qual_isImplied (qel))
2236 (FLG_ANNOTATIONERROR,
2237 message ("Alias qualifier %s used on unsharable storage type %t: %q",
2238 alkind_unparse (ak), ut, uentry_getName (ue)),
2239 uentry_whereLast (ue));
2246 if (uentry_isRefCounted (ue))
2248 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2249 || qual_isExposed (qel)
2250 || qual_isObserver (qel)))
2252 if (!qual_isImplied (qel))
2255 (FLG_ANNOTATIONERROR,
2257 ("Alias qualifier %s used on reference counted storage: %q",
2258 alkind_unparse (ak),
2259 uentry_unparse (ue)),
2260 uentry_whereLast (ue));
2268 if (qual_isRefQual (qel))
2271 (FLG_ANNOTATIONERROR,
2272 message ("Qualifier %s used on non-reference counted storage: %q",
2273 alkind_unparse (ak), uentry_unparse (ue)),
2274 uentry_whereLast (ue));
2283 uentry_setAliasKind (ue, ak);
2286 else if (qual_isNull (qel))
2288 if (uentry_isConstant (ue))
2292 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2293 uentry_whereDeclared (ue));
2297 uentry_setNullState (ue, NS_POSNULL);
2300 else if (qual_isRelNull (qel))
2302 uentry_setNullState (ue, NS_RELNULL);
2304 else if (qual_isNotNull (qel))
2306 uentry_setNullState (ue, NS_MNOTNULL);
2308 else if (qual_isAbstract (qel)
2309 || qual_isConcrete (qel))
2311 if (!uentry_isDatatype (ue))
2314 (FLG_ANNOTATIONERROR,
2315 message ("Qualifier %s used with non-datatype",
2316 qual_unparse (qel)),
2317 uentry_whereLast (ue));
2321 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2324 else if (qual_isMutable (qel))
2326 if (!uentry_isDatatype (ue))
2329 (FLG_ANNOTATIONERROR,
2330 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2331 uentry_whereLast (ue));
2335 if (!ynm_isOn (ue->info->datatype->mut))
2337 uentry_checkMutableType (ue);
2340 ue->info->datatype->mut = YES;
2343 else if (qual_isImmutable (qel))
2345 if (!uentry_isDatatype (ue))
2347 voptgenerror (FLG_ANNOTATIONERROR,
2348 message ("Qualifier %s used with non-datatype",
2349 qual_unparse (qel)),
2350 uentry_whereLast (ue));
2354 ue->info->datatype->mut = NO;
2357 else if (qual_isNullPred (qel))
2359 uentry_convertVarFunction (ue);
2361 if (uentry_isFunction (ue))
2363 ctype typ = uentry_getType (ue);
2364 ctype rtype = ctype_getReturnType (uentry_getType (ue));
2366 if (ctype_isRealBool (rtype))
2368 uentryList pl = ctype_argsFunction (typ);
2370 if (uentryList_size (pl) == 1)
2372 ue->info->fcn->nullPred = qel;
2376 voptgenerror (FLG_ANNOTATIONERROR,
2377 message ("Qualifier %s used with function having %d "
2378 "arguments (should have 1)",
2380 uentryList_size (pl)),
2381 uentry_whereLast (ue));
2386 voptgenerror (FLG_ANNOTATIONERROR,
2387 message ("Qualifier %s used with function returning %s "
2388 "(should return bool)",
2390 ctype_unparse (rtype)),
2391 uentry_whereLast (ue));
2396 voptgenerror (FLG_ANNOTATIONERROR,
2397 message ("Qualifier %s used with non-function",
2398 qual_unparse (qel)),
2399 uentry_whereLast (ue));
2402 else if (qual_isExitQual (qel))
2404 exitkind exk = exitkind_fromQual (qel);
2406 if (uentry_isFunction (ue))
2408 if (exitkind_isKnown (ue->info->fcn->exitCode))
2410 voptgenerror (FLG_ANNOTATIONERROR,
2411 message ("Multiple exit qualifiers used on function %q: %s, %s",
2412 uentry_getName (ue),
2413 exitkind_unparse (ue->info->fcn->exitCode),
2414 exitkind_unparse (exk)),
2415 uentry_whereLast (ue));
2418 ue->info->fcn->exitCode = exk;
2422 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2424 uentry_makeVarFunction (ue);
2425 ue->info->fcn->exitCode = exk;
2429 voptgenerror (FLG_ANNOTATIONERROR,
2430 message ("Exit qualifier %s used with non-function (type %s)",
2432 ctype_unparse (uentry_getType (ue))),
2433 uentry_whereLast (ue));
2437 else if (qual_isMetaState (qel))
2439 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2441 if (annotationInfo_matchesContext (ainfo, ue))
2443 DPRINTF (("Reflecting %s on %s",
2444 annotationInfo_unparse (ainfo),
2445 uentry_unparseFull (ue)));
2447 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2448 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2449 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2454 (FLG_ANNOTATIONERROR,
2455 message ("Attribute annotation %s used in inconsistent context: %q",
2457 uentry_unparse (ue)),
2458 uentry_whereLast (ue)))
2460 /*@i! annotationInfo_showContextError (ainfo, ue); */
2466 if (qual_isCQual (qel))
2472 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
2478 uentry_reflectQualifiers (uentry ue, qualList q)
2480 llassert (uentry_isValid (ue));
2482 DPRINTF (("Reflect qualifiers: %s / %s",
2483 uentry_unparseFull (ue), qualList_unparse (q)));
2485 qualList_elements (q, qel)
2487 if (qual_isStatic (qel))
2489 uentry_setStatic (ue);
2491 else if (qual_isUnused (qel))
2493 uentry_setUsed (ue, fileloc_undefined);
2495 else if (qual_isExternal (qel))
2497 fileloc_free (ue->whereDefined);
2498 ue->whereDefined = fileloc_createExternal ();
2500 else if (qual_isSef (qel))
2502 if (uentry_isVariable (ue))
2504 vkind vk = ue->info->var->kind;
2506 llassert (vk != VKREFPARAM);
2508 if (vk == VKYIELDPARAM)
2511 (FLG_ANNOTATIONERROR,
2512 message ("Qualifier sef cannot be used with %s: %q",
2513 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
2514 uentry_unparse (ue)),
2515 uentry_whereLast (ue));
2517 else if (vk == VKRETPARAM)
2519 ue->info->var->kind = VKSEFRETPARAM;
2523 ue->info->var->kind = VKSEFPARAM;
2529 (FLG_ANNOTATIONERROR,
2530 message ("Qualifier sef is meaningful only on parameters: %q",
2531 uentry_unparse (ue)),
2532 uentry_whereLast (ue));
2535 else if (qual_isExtern (qel))
2537 ue->storageclass = SCEXTERN;
2539 else if (qual_isGlobalQual (qel)) /* undef, killed */
2541 DPRINTF (("Reflecting qual: %s / %s",
2542 qual_unparse (qel), uentry_unparse (ue)));
2544 if (uentry_isVariable (ue))
2546 sstate oldstate = ue->info->var->defstate;
2547 sstate defstate = sstate_fromQual (qel);
2550 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2551 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2553 defstate = SS_UNDEFKILLED;
2560 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2561 ue->info->var->defstate = defstate;
2566 (FLG_ANNOTATIONERROR,
2567 message ("Qualifier %s used on non-variable: %q",
2568 qual_unparse (qel), uentry_unparse (ue)),
2569 uentry_whereLast (ue));
2572 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2574 /* start modifications */
2575 else if( qual_isBufQualifier(qel) ) {
2576 ctype ct = ctype_realType(uentry_getType(ue));
2577 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2579 if( uentry_hasBufStateInfo(ue) ) {
2580 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2582 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2583 /* If formal func param */
2584 uentry_setNullTerminatedState(ue);
2585 uentry_setLen (ue, 1);
2586 uentry_setSize (ue, 1);
2588 sRef_setNullTerminatedState(uentry_getSref(ue));
2589 sRef_setLen (uentry_getSref(ue), 1);
2590 sRef_setSize (uentry_getSref(ue), 1);
2592 uentry_setPossiblyNullTerminatedState(ue);
2594 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2598 /* put other BufState Qualifiers here */
2600 cstring s = uentry_getName(ue);
2601 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2602 struct for identifier %s\n", s) );
2604 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2606 sRef retSref = uentry_getSref (ue);
2607 ctype retType = sRef_getType (retSref);
2609 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2610 sRef_setNullTerminatedState (retSref);
2616 message ("Qualifier %s used on non-pointer on \
2617 function return: %q", qual_unparse (qel),
2618 uentry_unparse (ue)));
2625 message ("Qualifier %s used on non-pointer: %q",
2626 qual_unparse (qel), uentry_unparse (ue)));
2628 DPRINTF (("After: %s", uentry_unparseFull (ue)));
2630 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2632 ctype realType = ctype_realType (ue->utype);
2633 sstate defstate = sstate_fromQual (qel);
2635 if (ctype_isFunction (realType))
2637 realType = ctype_realType (ctype_getReturnType (realType));
2640 if (qual_isRelDef (qel))
2642 ; /* okay anywhere */
2646 if (!ctype_isAP (realType)
2647 && !ctype_isSU (realType)
2648 && !ctype_isUnknown (realType)
2649 && !ctype_isAbstract (ue->utype))
2652 (FLG_ANNOTATIONERROR,
2653 message ("Qualifier %s used on non-pointer or struct: %q",
2654 qual_unparse (qel), uentry_unparse (ue)),
2655 uentry_whereLast (ue));
2659 uentry_setDefState (ue, defstate);
2661 if (sRef_isStateSpecial (ue->sref)
2662 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2664 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2667 else if (qual_isYield (qel))
2669 if (uentry_isVariable (ue))
2671 ue->info->var->kind = VKYIELDPARAM;
2676 (FLG_ANNOTATIONERROR,
2677 message ("Qualifier %s used on non-iterator parameter: %q",
2678 qual_unparse (qel), uentry_unparse (ue)),
2679 uentry_whereLast (ue));
2682 else if (qual_isExQual (qel))
2684 exkind ek = exkind_fromQual (qel);
2685 ctype ut = uentry_getType (ue);
2687 DPRINTF (("Reflect ex qual: %s / %s",
2688 uentry_unparse (ue), exkind_unparse (ek)));
2690 if (ctype_isFunction (ut))
2692 ut = ctype_getReturnType (ut);
2695 if (!(ctype_isVisiblySharable (ut))
2696 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2697 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2699 if (!qual_isImplied (qel))
2701 if (ctype_isImmutableAbstract (ut)) {
2703 (FLG_REDUNDANTSHAREQUAL,
2704 message ("Qualifier %s used on unsharable storage type %t: %q",
2705 exkind_unparse (ek), ut, uentry_getName (ue)),
2706 uentry_whereLast (ue));
2709 (FLG_MISPLACEDSHAREQUAL,
2710 message ("Qualifier %s used on unsharable storage type %t: %q",
2711 exkind_unparse (ek), ut, uentry_getName (ue)),
2712 uentry_whereLast (ue));
2718 alkind ak = sRef_getAliasKind (ue->sref);
2720 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
2721 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
2723 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2725 if (!alkind_isTemp (ak))
2727 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
2728 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2731 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2732 || alkind_isOwned (ak))
2740 message ("Exposure qualifier %s used on %s storage (should "
2741 "be dependent): %q",
2743 alkind_unparse (ak),
2744 uentry_unparse (ue)));
2748 else if (qual_isGlobCheck (qel))
2750 if (uentry_isVariable (ue))
2752 chkind ch = chkind_fromQual (qel);
2754 if (ue->info->var->checked != CH_UNKNOWN)
2756 if (ch == ue->info->var->checked)
2758 llerror (FLG_SYNTAX,
2759 message ("Redundant %s qualifier on %q",
2761 uentry_getName (ue)));
2765 llerror (FLG_SYNTAX,
2767 ("Contradictory %s and %s qualifiers on %q",
2769 checkedName (ue->info->var->checked),
2770 uentry_getName (ue)));
2774 ue->info->var->checked = ch;
2780 message ("Qualifier %s used with non-variable",
2781 qual_unparse (qel)));
2784 else if (qual_isReturned (qel))
2786 if (uentry_isVariable (ue))
2788 ue->info->var->kind = VKRETPARAM;
2792 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2793 qual_unparse (qel)));
2798 uentry_reflectOtherQualifier (ue, qel);
2801 sRef_storeState (ue->sref);
2802 } end_qualList_elements;
2806 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
2810 uentry_isOnly (uentry ue)
2812 return (!uentry_isUndefined (ue)
2813 && uentry_isVariable (ue)
2814 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2818 uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2820 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2821 sRef_setOrigAliasKind (ue->sref, ak);
2825 uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2827 if (uentry_isVariable (ue))
2829 ue->info->var->nullstate = ns;
2832 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2836 uentry_isUnique (uentry ue)
2838 return (!uentry_isUndefined (ue)
2839 && uentry_isVariable (ue)
2840 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2844 uentry_isFileStatic (uentry ue)
2846 return (uentry_isStatic (ue)
2847 && (!uentry_isVariable (ue)
2848 || sRef_isFileStatic (uentry_getSref (ue))));
2852 uentry_isExported (uentry ue)
2854 if (uentry_isValid (ue))
2856 if (uentry_isVariable (ue))
2858 return (sRef_isRealGlobal (uentry_getSref (ue)));
2862 return !uentry_isStatic (ue);
2870 uentry_isNonLocal (uentry ue)
2872 return (uentry_isValid (ue) && uentry_isVariable (ue)
2873 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2877 uentry_isGlobalVariable (uentry ue)
2879 return (uentry_isValid (ue) && uentry_isVariable (ue)
2880 && sRef_isFileOrGlobalScope (ue->sref));
2884 uentry_isVisibleExternally (uentry ue)
2886 return (uentry_isValid (ue)
2887 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2888 || (!uentry_isStatic (ue)
2889 && (uentry_isFunction (ue)
2890 || uentry_isIter (ue)
2891 || uentry_isEndIter (ue)
2892 || uentry_isConstant (ue)
2893 || uentry_isDatatype (ue)
2894 || uentry_isAnyTag (ue)))));
2898 uentry_isPrintfLike (uentry ue)
2900 return (uentry_isFunction (ue)
2901 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2905 uentry_isScanfLike (uentry ue)
2907 return (uentry_isFunction (ue)
2908 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2912 uentry_isMessageLike (uentry ue)
2914 return (uentry_isFunction (ue)
2915 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2918 static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2920 uentryList args = uentry_getParams (ue);
2922 if (!uentryList_isMissingParams (args))
2924 uentry last = uentry_undefined;
2926 uentryList_elements (args, current)
2928 if (uentry_isElipsisMarker (current))
2930 if (uentry_isUndefined (last))
2934 message ("Function %q is marked %s, but has no format "
2935 "string argument before elipsis",
2936 uentry_getName (ue),
2937 specCode_unparse (ue->info->fcn->specialCode)),
2938 uentry_whereLast (ue));
2939 ue->info->fcn->specialCode = SPC_NONE;
2943 ctype rt = ctype_realType (uentry_getType (last));
2945 if (!ctype_match (rt, ctype_string))
2949 /* wchar_t * is okay too */
2950 if (ctype_isAP (rt))
2952 ctype base = ctype_baseArrayPtr (rt);
2954 if (ctype_isArbitraryIntegral (base))
2964 message ("Function %q is marked %s, but the argument "
2965 "before the elipsis has type %s (should be char *)",
2966 uentry_getName (ue),
2967 specCode_unparse (ue->info->fcn->specialCode),
2968 ctype_unparse (uentry_getType (last))),
2969 uentry_whereLast (ue));
2971 ue->info->fcn->specialCode = SPC_NONE;
2978 } end_uentryList_elements ;
2982 message ("Function %q is marked %s, but has no elipsis parameter",
2983 uentry_getName (ue),
2984 specCode_unparse (ue->info->fcn->specialCode)),
2985 uentry_whereLast (ue));
2987 ue->info->fcn->specialCode = SPC_NONE;
2992 uentry_setPrintfLike (uentry ue)
2994 uentry_convertVarFunction (ue);
2995 llassertfatal (uentry_isFunction (ue));
2996 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
2997 checkSpecialFunction (ue);
3001 uentry_setScanfLike (uentry ue)
3003 uentry_convertVarFunction (ue);
3004 llassertfatal (uentry_isFunction (ue));
3005 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3006 checkSpecialFunction (ue);
3010 uentry_setMessageLike (uentry ue)
3012 uentry_convertVarFunction (ue);
3013 llassertfatal (uentry_isFunction (ue));
3014 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3015 checkSpecialFunction (ue);
3019 uentry_isSpecialFunction (uentry ue)
3021 return (uentry_isFunction (ue)
3022 && (ue->info->fcn->specialCode != SPC_NONE));
3025 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3027 ctype ct = idDecl_getCtype (t);
3029 fileloc loc = setLocation ();
3030 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3031 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
3033 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
3034 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3035 uentry_implicitParamAnnots (ue);
3037 /* Parameter type [][] or [x][] is invalid */
3039 while (ctype_isFixedArray (base)) {
3040 base = ctype_baseArrayPtr (base);
3043 if (ctype_isIncompleteArray (base)) {
3044 base = ctype_baseArrayPtr (base);
3046 if (ctype_isArray (base)) {
3047 if (!uentry_hasName (ue)) {
3048 (void) optgenerror (FLG_INCOMPLETETYPE,
3049 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3051 ctype_unparse (ct)),
3052 uentry_whereLast (ue));
3054 (void) optgenerror (FLG_INCOMPLETETYPE,
3055 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3056 uentry_getName (ue),
3057 ctype_unparse (ct)),
3058 uentry_whereLast (ue));
3063 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
3067 /*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3069 ctype ct = idDecl_getCtype (t);
3071 if (ctype_isFunction (ct))
3073 return (uentry_makeIdFunction (t));
3077 fileloc loc = setLocation ();
3078 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3080 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3082 if (!uentry_isExtern (ue))
3084 uentry_setDefined (ue, loc);
3092 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
3094 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
3102 /*@only@*/ /*@notnull@*/
3103 uentry uentry_makeConstantAux (cstring n, ctype t,
3104 /*@keep@*/ fileloc f, bool priv,
3105 /*@only@*/ multiVal m)
3107 uentry e = uentry_alloc ();
3110 e->uname = cstring_copy (n);
3112 e->storageclass = SCNONE;
3114 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3116 e->sref = sRef_makeConst (t);
3121 e->uses = filelocList_new ();
3122 e->isPrivate = priv;
3123 e->hasNameError = FALSE;
3125 e->info = (uinfo) dmalloc (sizeof (*e->info));
3126 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
3127 e->info->uconst->access = typeIdSet_undefined;
3129 uentry_setSpecDef (e, f);
3131 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3133 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3136 uentry_setConstantValue (e, m);
3141 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3143 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
3146 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3148 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3149 idDecl_getCtype (t),
3152 llassert (fileloc_isUndefined (ue->whereDeclared));
3153 ue->whereDeclared = setLocation ();
3154 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3156 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
3157 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
3165 void uentry_setDefState (uentry ue, sstate defstate)
3167 if (uentry_isValid (ue))
3169 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3171 if (uentry_isVariable (ue))
3173 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3178 bool uentry_isCheckedUnknown (uentry ue)
3180 return (uentry_isVar (ue)
3181 && (ue->info->var->checked == CH_UNKNOWN));
3184 bool uentry_isCheckMod (uentry ue)
3186 return (uentry_isVar (ue)
3187 && (ue->info->var->checked == CH_CHECKMOD));
3190 bool uentry_isUnchecked (uentry ue)
3192 return (uentry_isVar (ue)
3193 && (ue->info->var->checked == CH_UNCHECKED));
3196 bool uentry_isChecked (uentry ue)
3198 return (uentry_isVar (ue)
3199 && (ue->info->var->checked == CH_CHECKED));
3202 bool uentry_isCheckedModify (uentry ue)
3204 return (uentry_isVar (ue)
3205 && (ue->info->var->checked == CH_CHECKED
3206 || ue->info->var->checked == CH_CHECKMOD
3207 || ue->info->var->checked == CH_CHECKEDSTRICT));
3210 bool uentry_isCheckedStrict (uentry ue)
3212 return (uentry_isVar (ue)
3213 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3216 void uentry_setUnchecked (uentry ue)
3218 llassert (uentry_isVar (ue));
3220 ue->info->var->checked = CH_UNCHECKED;
3223 void uentry_setChecked (uentry ue)
3225 llassert (uentry_isVar (ue));
3227 ue->info->var->checked = CH_CHECKED;
3230 void uentry_setCheckMod (uentry ue)
3232 llassert (uentry_isVar (ue));
3234 ue->info->var->checked = CH_CHECKMOD;
3237 void uentry_setCheckedStrict (uentry ue)
3239 llassert (uentry_isVar (ue));
3241 ue->info->var->checked = CH_CHECKEDSTRICT;
3244 static /*@only@*/ /*@notnull@*/
3245 uentry uentry_makeVariableAux (cstring n, ctype t,
3247 /*@exposed@*/ sRef s,
3248 bool priv, vkind kind)
3250 uentry e = uentry_alloc ();
3253 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3256 e->uname = cstring_copy (n);
3259 e->storageclass = SCNONE;
3261 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3268 e->uses = filelocList_new ();
3269 e->isPrivate = priv;
3270 e->hasNameError = FALSE;
3272 e->info = (uinfo) dmalloc (sizeof (*e->info));
3273 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3274 e->info->var->kind = kind;
3276 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
3277 e->info->var->checked = CH_UNKNOWN;
3279 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3280 uentry_setSpecDef (e, f);
3281 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3283 if (ctype_isFunction (rt))
3285 rt = ctype_getReturnType (rt);
3288 if (ctype_isUA (rt))
3290 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3291 sRef_setStateFromType (e->sref, rt);
3294 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
3295 e->info->var->defstate = sRef_getDefState (e->sref);
3296 e->info->var->nullstate = sRef_getNullState (e->sref);
3298 /* start modifications */
3299 /* This function sets the uentry for a pointer or array variable declaration,
3300 it allocates memory and sets the fields. We check if the type of the variable
3301 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3303 if( ctype_isArray (t) || ctype_isPointer(t)) {
3304 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3305 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
3306 /*@access sRef@*/ /*i@222*/
3307 /* It probably isn't necessary to violate the abstraction here
3310 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
3313 e->info->var->bufinfo = NULL;
3315 /* end modification */
3321 uentry_isYield (uentry ue)
3323 return (uentry_isVariable (ue)
3324 && (ue->info->var->kind == VKYIELDPARAM
3325 || ue->info->var->kind == VKREFYIELDPARAM));
3329 uentry_isRefsField (uentry ue)
3331 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3334 /*@only@*/ /*@notnull@*/
3335 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3337 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3338 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3345 void uentry_makeVarFunction (uentry ue)
3352 llassert (uentry_isValid (ue));
3353 llassert (!sRef_modInFunction ());
3355 ak = sRef_getOrigAliasKind (ue->sref);
3356 ek = sRef_getOrigExKind (ue->sref);
3358 llassert (uentry_isVariable (ue));
3359 oldInfo = ue->info->var;
3361 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3364 ** expanded macro is marked used (until I write a pre-processor)
3367 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
3370 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3371 ue->info->fcn->exitCode = XK_UNKNOWN;
3372 ue->info->fcn->nullPred = qual_createUnknown ();
3373 ue->info->fcn->specialCode = SPC_NONE;
3374 ue->info->fcn->access = typeIdSet_undefined;
3375 ue->info->fcn->hasGlobs = FALSE;
3376 ue->info->fcn->globs = globSet_undefined;
3377 ue->info->fcn->hasMods = FALSE;
3378 ue->info->fcn->mods = sRefSet_undefined;
3379 ue->info->fcn->specclauses = NULL;
3380 ue->info->fcn->defparams = uentryList_undefined;
3383 ue->info->fcn->preconditions = functionConstraint_undefined;
3387 ue->info->fcn->postconditions = functionConstraint_undefined;
3390 if (ctype_isFunction (ue->utype))
3392 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3396 ue->sref = sRef_makeType (ctype_unknown);
3399 if (sRef_isRefCounted (ue->sref))
3405 if (alkind_isUnknown (ak))
3407 if (exkind_isKnown (ek))
3409 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3410 ak = AK_IMPDEPENDENT;
3414 if (context_getFlag (FLG_RETIMPONLY))
3416 if (ctype_isFunction (ue->utype)
3417 && ctype_isVisiblySharable
3418 (ctype_realType (ctype_getReturnType (ue->utype))))
3420 if (uentryList_hasReturned (uentry_getParams (ue)))
3426 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3441 loc = ue->whereDeclared;
3443 sRef_setAliasKind (ue->sref, ak, loc);
3444 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3445 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3446 sRef_setExKind (ue->sref, ek, loc);
3448 if (oldInfo->kind == VKEXPMACRO)
3454 fileloc_free (ue->whereDefined);
3455 ue->whereDefined = fileloc_undefined;
3458 uvinfo_free (oldInfo);
3461 void uentry_makeConstantFunction (uentry ue)
3468 llassert (uentry_isValid (ue));
3469 llassert (!sRef_modInFunction ());
3471 ak = sRef_getOrigAliasKind (ue->sref);
3472 ek = sRef_getOrigExKind (ue->sref);
3474 llassert (uentry_isConstant (ue));
3475 oldInfo = ue->info->uconst;
3477 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3480 ** expanded macro is marked used (until I write a pre-processor)
3484 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3485 ue->info->fcn->exitCode = XK_UNKNOWN;
3486 ue->info->fcn->nullPred = qual_createUnknown ();
3487 ue->info->fcn->specialCode = SPC_NONE;
3488 ue->info->fcn->access = typeIdSet_undefined;
3489 ue->info->fcn->hasGlobs = FALSE;
3490 ue->info->fcn->globs = globSet_undefined;
3491 ue->info->fcn->hasMods = FALSE;
3492 ue->info->fcn->mods = sRefSet_undefined;
3493 ue->info->fcn->specclauses = NULL;
3494 ue->info->fcn->defparams = uentryList_undefined;
3497 ue->info->fcn->preconditions = functionConstraint_undefined;
3501 ue->info->fcn->postconditions = functionConstraint_undefined;
3505 if (ctype_isFunction (ue->utype))
3507 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3511 ue->sref = sRef_makeType (ctype_unknown);
3514 if (sRef_isRefCounted (ue->sref))
3520 if (alkind_isUnknown (ak))
3522 if (exkind_isKnown (ek))
3524 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3525 ak = AK_IMPDEPENDENT;
3529 if (context_getFlag (FLG_RETIMPONLY))
3531 if (ctype_isFunction (ue->utype)
3532 && ctype_isVisiblySharable
3533 (ctype_realType (ctype_getReturnType (ue->utype))))
3535 if (uentryList_hasReturned (uentry_getParams (ue)))
3541 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3556 loc = ue->whereDeclared;
3558 sRef_setAliasKind (ue->sref, ak, loc);
3559 sRef_setExKind (ue->sref, ek, loc);
3561 fileloc_free (ue->whereDefined);
3562 ue->whereDefined = fileloc_undefined;
3563 ucinfo_free (oldInfo);
3567 uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3569 llassert (uentry_isValid (ue));
3571 if (uentry_isIter (ue))
3573 llassert (globSet_isUndefined (ue->info->iter->globs));
3574 ue->info->iter->globs = globs;
3578 uentry_convertVarFunction (ue);
3580 llassert (uentry_isFunction (ue));
3581 llassert (!ue->info->fcn->hasGlobs
3582 && globSet_isUndefined (ue->info->fcn->globs));
3584 ue->info->fcn->hasGlobs = TRUE;
3585 globSet_markImmutable (globs);
3586 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3591 /* ??? - evans 2001-09-09 not sure what's going on here...?
3592 if (globSet_hasStatic (globs))
3594 context_recordFileGlobals (globs);
3598 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3600 ue->info->fcn->hasMods = TRUE;
3604 void uentry_addAccessType (uentry ue, typeId tid)
3606 if (uentry_isFunction (ue))
3608 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3610 else if (uentry_isEitherConstant (ue))
3612 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3614 else if (uentry_isIter (ue))
3616 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3618 else if (uentry_isEndIter (ue))
3620 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3624 llbug (message ("no access for: %q", uentry_unparse (ue)));
3628 /*@only@*/ /*@notnull@*/ uentry
3629 uentry_makeFunction (cstring n, ctype t,
3631 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
3632 /*@only@*/ warnClause warn,
3635 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
3636 return (uentry_makeFunctionAux (n, t,
3637 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3638 : typeIdSet_single (access)),
3645 /*@notnull@*/ uentry
3646 uentry_makePrivFunction2 (cstring n, ctype t,
3648 globSet globs, sRefSet mods,
3651 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3656 /*@notnull@*/ uentry
3657 uentry_makeSpecFunction (cstring n, ctype t,
3659 /*@only@*/ globSet globs,
3660 /*@only@*/ sRefSet mods,
3663 uentry ue = uentry_makeFunctionAux (n, t, access,
3664 globs, mods, warnClause_undefined,
3667 uentry_setHasGlobs (ue);
3668 uentry_setHasMods (ue);
3670 reflectImplicitFunctionQualifiers (ue, TRUE);
3675 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3677 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3678 sRef_undefined, FALSE, VKEXPMACRO);
3680 uentry_setDefined (ue, f);
3684 /*@notnull@*/ /*@notnull@*/ uentry
3685 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3687 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3688 typeIdSet_singleOpt (access),
3689 globSet_undefined, sRefSet_undefined,
3690 warnClause_undefined,
3694 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3698 bool uentry_isForward (uentry e)
3700 if (uentry_isValid (e))
3702 ctype ct = uentry_getType (e);
3704 return (ctype_isUnknown (ct)
3705 || (ctype_isFunction (ct)
3706 && ctype_isUnknown (ctype_getReturnType (ct))));
3713 /*@notnull@*/ uentry
3714 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3716 return (uentry_makeFunctionAux (n, ctype_unknown, access,
3717 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3721 /*@notnull@*/ uentry
3722 uentry_makeUnspecFunction (cstring n, ctype t,
3726 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3727 sRefSet_undefined, warnClause_undefined,
3730 reflectImplicitFunctionQualifiers (ue, TRUE);
3739 /* is exported for use by usymtab_interface */
3741 /*@notnull@*/ uentry
3742 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
3743 fileloc f, bool priv)
3745 uentry e = uentry_alloc ();
3747 DPRINTF (("Make datatype: %s / %s",
3748 n, ctype_unparse (t)));
3750 /* e->shallowCopy = FALSE; */
3751 e->ukind = KDATATYPE;
3752 e->uname = cstring_copy (n);
3754 e->storageclass = SCNONE;
3755 e->sref = sRef_makeUnknown ();
3759 sRef_setStateFromType (e->sref, t);
3762 uentry_setSpecDef (e, f);
3764 e->warn = warnClause_undefined; /*@i634@*/
3765 e->uses = filelocList_new ();
3766 e->isPrivate = priv;
3767 e->hasNameError = FALSE;
3772 e->info = (uinfo) dmalloc (sizeof (*e->info));
3773 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3774 e->info->datatype->abs = abstract;
3775 e->info->datatype->mut = mut;
3776 e->info->datatype->type = ctype_undefined;
3778 if (uentry_isDeclared (e))
3780 uentry_setDefined (e, f);
3783 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
3785 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3791 /*@notnull@*/ uentry
3792 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
3794 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
3797 /*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
3799 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
3800 ctype_bool, NO, abstract,
3801 fileloc_getBuiltin (),
3804 ret->info->datatype->type = ctype_bool;
3812 static /*@only@*/ /*@notnull@*/ uentry
3813 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3814 /*@only@*/ fileloc f)
3816 uentry e = uentry_alloc ();
3819 e->uname = cstring_copy (n);
3821 e->sref = sRef_makeUnknown ();
3822 e->storageclass = SCNONE;
3826 uentry_setSpecDef (e, f);
3828 e->warn = warnClause_undefined; /*@i452@*/
3829 e->uses = filelocList_new ();
3830 e->isPrivate = FALSE;
3831 e->hasNameError = FALSE;
3833 e->info = (uinfo) dmalloc (sizeof (*e->info));
3834 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3835 e->info->iter->access = access;
3836 e->info->iter->mods = sRefSet_undefined;
3837 e->info->iter->globs = globSet_undefined;
3839 uentry_checkIterArgs (e);
3843 /*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3845 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3848 static /*@notnull@*/ uentry
3849 uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3851 uentry e = uentry_alloc ();
3853 /* e->shallowCopy = FALSE; */
3854 e->ukind = KENDITER;
3855 e->storageclass = SCNONE;
3856 e->uname = message ("end_%s", n);
3857 e->utype = ctype_unknown;
3858 e->sref = sRef_makeUnknown ();
3860 uentry_setSpecDef (e, f);
3865 e->uses = filelocList_new ();
3866 e->isPrivate = FALSE;
3867 e->hasNameError = FALSE;
3869 e->info = (uinfo) dmalloc (sizeof (*e->info));
3870 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3872 e->info->enditer->access = access;
3874 e->warn = warnClause_undefined; /*@i452@*/
3878 /*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3880 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3887 static /*@only@*/ /*@notnull@*/ uentry
3888 uentry_makeTagAux (cstring n, ctype t,
3889 /*@only@*/ fileloc fl,
3890 bool priv, ekind kind)
3892 uentry e = uentry_alloc ();
3894 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3896 llbuglit ("uentry_makeTagAux: not a tag type");
3900 /* e->shallowCopy = FALSE; */
3901 e->uname = cstring_copy (n);
3904 e->sref = sRef_makeUnknown ();
3905 e->storageclass = SCNONE;
3907 uentry_setSpecDef (e, fl);
3912 e->uses = filelocList_new ();
3913 e->isPrivate = priv;
3914 e->hasNameError = FALSE;
3916 e->info = (uinfo) dmalloc (sizeof (*e->info));
3917 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3918 e->info->datatype->abs = NO;
3919 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3920 e->info->datatype->type = t;
3921 e->warn = warnClause_undefined; /*@i452@*/
3923 if (uentry_isDeclared (e))
3925 uentry_setDefined (e, fl);
3931 uentry uentry_makeStructTagLoc (cstring n, ctype t)
3933 cstring sname = makeStruct (n);
3934 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3936 cstring_free (sname);
3941 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3943 cstring sname = makeStruct (n);
3944 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3946 cstring_free (sname);
3951 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3953 cstring uname = makeUnion (n);
3954 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3956 cstring_free (uname);
3962 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3964 cstring ename = makeEnum (n);
3965 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3967 cstring_free (ename);
3973 uentry_makeUnionTagLoc (cstring n, ctype t)
3975 cstring uname = makeUnion (n);
3976 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3978 cstring_free (uname);
3983 uentry_makeEnumTagLoc (cstring n, ctype t)
3985 cstring ename = makeEnum (n);
3986 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
3988 cstring_free (ename);
3993 uentry_isStructTag (uentry ue)
3995 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
3999 uentry_isUnionTag (uentry ue)
4001 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4005 uentry_isEnumTag (uentry ue)
4007 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4011 uentry_isAnyTag (uentry ue)
4013 return (uentry_isStructTag (ue)
4014 || uentry_isUnionTag (ue)
4015 || uentry_isEnumTag (ue));
4018 static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4020 extern void uentry_destroyMod (void)
4021 /*@globals killed emarker@*/ /*@modifies emarker@*/
4023 static bool wasDestroyed = FALSE;
4025 llassert (!wasDestroyed);
4027 if (emarker != NULL)
4029 uentry_reallyFree (emarker);
4032 wasDestroyed = TRUE;
4036 uentry_makeElipsisMarker (void)
4038 if (emarker == NULL)
4040 emarker = uentry_alloc ();
4042 emarker->ukind = KELIPSMARKER;
4043 emarker->uname = cstring_makeLiteral ("...");
4044 emarker->utype = ctype_elipsMarker;
4045 emarker->sref = sRef_undefined;
4046 emarker->storageclass = SCNONE;
4047 emarker->used = FALSE;
4048 emarker->lset = FALSE;
4049 emarker->info = NULL;
4051 uentry_setSpecDef (emarker, fileloc_undefined);
4052 emarker->uses = filelocList_new ();
4053 emarker->isPrivate = FALSE;
4054 emarker->hasNameError = FALSE;
4057 /*@ignore@*/ return (emarker); /*@end@*/
4065 uentry_equiv (uentry p1, uentry p2)
4067 if (uentry_compare (p1, p2) != 0)
4078 uentry_xcomparealpha (uentry *p1, uentry *p2)
4082 if ((res = uentry_compare (*p1, *p2)) == 0) {
4083 if ((*p1 != NULL) && (*p2 != NULL)) {
4084 res = cstring_compare ((*p1)->uname,
4093 uentry_xcompareuses (uentry *p1, uentry *p2)
4098 if (uentry_isValid (u1))
4100 if (uentry_isValid (u2))
4102 return (-1 * int_compare (filelocList_size (u1->uses),
4103 filelocList_size (u2->uses)));
4112 if (uentry_isValid (u2))
4124 uentry_compareStrict (uentry v1, uentry v2)
4126 COMPARERETURN (uentry_compare (v1, v2));
4128 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4130 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4131 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4132 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4139 uentry_compare (uentry u1, uentry u2)
4141 if (u1 == u2) return 0;
4143 if (uentry_isInvalid (u1)) return -1;
4144 if (uentry_isInvalid (u2)) return 1;
4146 INTCOMPARERETURN (u1->ukind, u2->ukind);
4147 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4148 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
4149 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4155 /* bug detected by lclint:
4156 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4161 return (multiVal_compare (uentry_getConstantValue (u1),
4162 uentry_getConstantValue (u2)));
4166 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4168 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4169 uentry_accessType (u2)));
4170 return (uentryList_compareParams (uentry_getParams (u1),
4171 uentry_getParams (u2)));
4173 return (typeIdSet_compare (uentry_accessType (u1),
4174 uentry_accessType (u2)));
4177 ** Functions are never equivalent
4180 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
4190 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4191 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4192 sRef_getOrigAliasKind (u2->sref)));
4193 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4194 sRef_getOrigExKind (u2->sref)));
4195 COMPARERETURN (generic_compare (u1->info->var->checked,
4196 u2->info->var->checked));
4197 COMPARERETURN (generic_compare (u1->info->var->defstate,
4198 u2->info->var->defstate));
4199 return (generic_compare (u1->info->var->nullstate,
4200 u2->info->var->nullstate));
4202 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4203 u2->info->datatype->type));
4204 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4205 u2->info->datatype->mut));
4206 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4215 ** all entries are: <type>[@<info>]*#<name>
4217 ** info depends on kind:
4221 advanceField (char **s)
4223 reader_checkChar (s, '@');
4227 advanceName (char **s)
4229 reader_checkChar (s, '#');
4233 vkind_fromInt (int i)
4235 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4237 llbuglit ("vkind_fromInt: out of range");
4244 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4245 typeIdSet access, nstate nullstate,
4246 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4248 uentry e = uentry_alloc ();
4253 e->sref = sRef_makeConst (ct);
4255 sRef_setNullState (e->sref, nullstate, loc);
4256 e->storageclass = SCNONE;
4258 if (fileloc_isSpec (loc))
4260 e->whereSpecified = loc;
4261 e->whereDeclared = fileloc_undefined;
4265 e->whereSpecified = fileloc_undefined;
4266 e->whereDeclared = loc;
4269 e->whereDefined = fileloc_undefined;
4270 e->uses = filelocList_new ();
4271 e->isPrivate = FALSE;
4272 e->hasNameError = FALSE;
4277 e->warn = warnClause_undefined; /*@i452@*/
4279 e->info = (uinfo) dmalloc (sizeof (*e->info));
4280 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
4281 e->info->uconst->access = access;
4283 uentry_setConstantValue (e, m);
4284 sRef_storeState (e->sref);
4289 static /*@only@*/ uentry
4290 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4291 sstate defstate, nstate isnull, alkind aliased,
4292 exkind exp, chkind checked,
4293 /*@only@*/ fileloc loc)
4295 uentry e = uentry_alloc ();
4300 e->storageclass = SCNONE;
4302 e->sref = sRef_makeType (ct);
4303 sRef_setNullState (e->sref, isnull, loc);
4305 e->whereDefined = fileloc_undefined;
4307 if (fileloc_isSpec (loc))
4309 e->whereSpecified = loc;
4310 e->whereDeclared = fileloc_undefined;
4314 e->whereSpecified = fileloc_undefined;
4315 e->whereDeclared = loc;
4318 e->isPrivate = FALSE;
4319 e->hasNameError = FALSE;
4324 e->uses = filelocList_new ();
4325 e->warn = warnClause_undefined; /*@i452@*/
4327 e->info = (uinfo) dmalloc (sizeof (*e->info));
4328 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4329 e->info->var->kind = kind;
4330 e->info->var->checked = checked;
4331 e->info->var->defstate = defstate;
4333 sRef_setDefState (e->sref, defstate, loc);
4335 e->info->var->nullstate = sRef_getNullState (e->sref);
4337 sRef_setExKind (e->sref, exp, loc);
4338 sRef_setAliasKind (e->sref, aliased, loc);
4340 sRef_storeState (e->sref);
4342 /*DRL ADDED 9-1-2000 */
4343 e->info->var->bufinfo = NULL;
4348 static /*@only@*/ uentry
4349 uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
4350 ynm mut, ctype rtype, alkind ak, exkind exp,
4351 sstate defstate, nstate isnull,
4352 /*@only@*/ fileloc loc)
4354 uentry e = uentry_alloc ();
4356 e->ukind = KDATATYPE;
4357 /* e->shallowCopy = FALSE; */
4360 e->storageclass = SCNONE;
4361 e->sref = sRef_makeUnknown ();
4362 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
4365 ** This is only setting null state. (I think?)
4368 if (ctype_isUA (ct))
4370 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4372 if (uentry_isValid (te))
4374 sRef_setStateFromUentry (e->sref, te);
4378 /* problem for recursive type definitions */
4382 sRef_setAliasKind (e->sref, ak, loc);
4383 sRef_setExKind (e->sref, exp, loc);
4385 sRef_setDefState (e->sref, defstate, loc);
4387 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
4389 isnull = NS_ABSNULL;
4392 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
4393 sRef_mergeNullState (e->sref, isnull);
4395 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4397 if (fileloc_isSpec (loc))
4399 e->whereSpecified = loc;
4400 e->whereDeclared = fileloc_undefined;
4404 e->whereSpecified = fileloc_undefined;
4405 e->whereDeclared = loc;
4408 e->isPrivate = FALSE;
4409 e->hasNameError = FALSE;
4411 e->warn = warnClause_undefined; /*@i452@*/
4415 e->uses = filelocList_new ();
4417 e->info = (uinfo) dmalloc (sizeof (*e->info));
4418 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4419 e->info->datatype->abs = abstract;
4420 e->info->datatype->mut = mut;
4421 e->info->datatype->type = rtype;
4423 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
4424 sRef_storeState (e->sref);
4425 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
4431 static void uentry_setHasGlobs (uentry ue)
4433 llassert (uentry_isFunction (ue));
4435 ue->info->fcn->hasGlobs = TRUE;
4438 static void uentry_setHasMods (uentry ue)
4440 llassert (uentry_isFunction (ue));
4442 ue->info->fcn->hasMods = TRUE;
4446 bool uentry_hasGlobs (uentry ue)
4448 if (uentry_isFunction (ue))
4450 return (ue->info->fcn->hasGlobs);
4456 bool uentry_hasStateClauseList (uentry ue)
4458 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
4461 bool uentry_hasConditions (uentry ue)
4463 return (uentry_isFunction (ue)
4464 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4465 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4468 stateClauseList uentry_getStateClauseList (uentry ue)
4470 if (!uentry_isFunction (ue))
4472 llassert (uentry_isFunction (ue));
4473 return stateClauseList_undefined;
4476 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
4477 return ue->info->fcn->specclauses;
4480 bool uentry_hasMods (uentry ue)
4482 if (uentry_isFunction (ue))
4484 return (ue->info->fcn->hasMods);
4491 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4493 bool hasGlobs, /*@only@*/ globSet globs,
4494 bool hasMods, /*@only@*/ sRefSet mods,
4495 alkind ak, exkind exp,
4496 sstate defstate, nstate isnull,
4500 /*@only@*/ stateClauseList specclauses,
4501 /*@only@*/ warnClause warnclause,
4502 /*@only@*/ fileloc loc)
4504 uentry e = uentry_alloc ();
4507 /* e->shallowCopy = FALSE; */
4511 e->storageclass = SCNONE;
4513 if (ctype_isFunction (ct))
4515 ret = ctype_getReturnType (ct);
4519 if (ctype_isKnown (ct))
4521 llbug (message ("not function: %s", ctype_unparse (ct)));
4524 ret = ctype_unknown;
4527 e->sref = sRef_makeType (ret);
4529 if (ctype_isUA (ret))
4531 sRef_setStateFromType (e->sref, ret);
4534 sRef_setDefined (e->sref, loc);
4535 sRef_setNullState (e->sref, isnull, loc);
4537 sRef_setAliasKind (e->sref, ak, loc);
4538 sRef_setExKind (e->sref, exp, loc);
4539 sRef_setDefState (e->sref, defstate, loc);
4541 e->whereSpecified = loc;
4542 e->whereDefined = fileloc_undefined;
4544 e->isPrivate = FALSE;
4545 e->hasNameError = FALSE;
4549 e->uses = filelocList_new ();
4550 e->warn = warnclause;
4552 e->info = (uinfo) dmalloc (sizeof (*e->info));
4553 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4555 e->info->fcn->exitCode = exitCode;
4556 e->info->fcn->specialCode = sCode;
4557 e->info->fcn->nullPred = nullPred;
4558 e->info->fcn->access = access;
4560 e->info->fcn->specclauses = specclauses;
4561 e->info->fcn->hasGlobs = hasGlobs;
4562 e->info->fcn->globs = globs;
4564 e->info->fcn->hasMods = hasMods;
4565 e->info->fcn->mods = mods;
4567 e->info->fcn->defparams = uentryList_undefined;
4568 e->whereDeclared = fileloc_undefined;
4570 sRef_storeState (e->sref);
4573 e->info->fcn->preconditions = NULL;
4577 e->info->fcn->postconditions = NULL;
4583 static /*@only@*/ uentry
4584 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4585 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4587 uentry e = uentry_alloc ();
4589 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4591 llbuglit ("uentry_makeTagBase: not a tag type");
4594 /* e->shallowCopy = FALSE; */
4598 e->sref = sRef_makeUnknown ();
4599 e->storageclass = SCNONE;
4601 if (fileloc_isSpec (loc))
4603 e->whereSpecified = loc;
4604 e->whereDeclared = fileloc_undefined;
4608 e->whereDeclared = loc;
4609 e->whereSpecified = fileloc_undefined;
4612 e->whereDefined = fileloc_undefined;
4614 e->isPrivate = FALSE;
4615 e->hasNameError = FALSE;
4619 e->uses = filelocList_new ();
4620 e->warn = warnClause_undefined; /*@i452@*/
4622 e->info = (uinfo) dmalloc (sizeof (*e->info));
4623 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4624 e->info->datatype->abs = NO;
4625 e->info->datatype->mut = MAYBE;
4626 e->info->datatype->type = rtype;
4628 sRef_storeState (e->sref);
4634 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4635 ctype ct, /*@only@*/ fileloc loc)
4637 uentry e = uentry_alloc ();
4639 /* e->shallowCopy = FALSE; */
4643 e->sref = sRef_makeUnknown ();
4644 e->storageclass = SCNONE;
4646 if (fileloc_isSpec (loc))
4648 e->whereSpecified = loc;
4649 e->whereDeclared = fileloc_undefined;
4653 e->whereDeclared = loc;
4654 e->whereSpecified = fileloc_undefined;
4657 e->whereDefined = fileloc_undefined;
4659 e->isPrivate = FALSE;
4660 e->hasNameError = FALSE;
4664 e->uses = filelocList_new ();
4665 e->warn = warnClause_undefined; /*@i452@*/
4667 e->info = (uinfo) dmalloc (sizeof (*e->info));
4668 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4669 e->info->iter->access = access;
4670 e->info->iter->mods = sRefSet_undefined;
4671 e->info->iter->globs = globSet_undefined;
4673 sRef_storeState (e->sref);
4678 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4679 /*@only@*/ fileloc loc)
4681 uentry e = uentry_alloc ();
4683 /* e->shallowCopy = FALSE; */
4684 e->ukind = KENDITER;
4685 e->storageclass = SCNONE;
4687 e->utype = ctype_unknown;
4688 e->sref = sRef_makeUnknown ();
4690 if (fileloc_isSpec (loc))
4692 e->whereSpecified = loc;
4693 e->whereDeclared = fileloc_undefined;
4697 e->whereDeclared = loc;
4698 e->whereSpecified = fileloc_undefined;
4701 e->whereDefined = fileloc_undefined;
4703 e->isPrivate = FALSE;
4704 e->hasNameError = FALSE;
4708 e->uses = filelocList_new ();
4709 e->warn = warnClause_undefined; /*@i452@*/
4711 e->info = (uinfo) dmalloc (sizeof (*e->info));
4712 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4713 e->info->enditer->access = access;
4714 sRef_storeState (e->sref);
4719 void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4727 uentry_undump (ekind kind, fileloc loc, char **s)
4731 DPRINTF (("Uentry undump: %s", *s));
4735 reader_checkChar (s, '!');
4736 reader_checkChar (s, '.');
4737 ue = uentry_makeElipsisMarker ();
4741 ctype ct = ctype_undump (s);
4755 reader_checkChar (s, '|');
4757 if (reader_optCheckChar (s, '@'))
4759 tkind = vkind_fromInt (reader_getInt (s));
4760 reader_checkChar (s, '|');
4767 if (reader_optCheckChar (s, '$'))
4769 defstate = SS_UNKNOWN;
4770 isnull = NS_UNKNOWN;
4771 aliased = AK_IMPTEMP;
4773 checked = CH_UNKNOWN;
4775 else if (reader_optCheckChar (s, '&'))
4777 defstate = SS_DEFINED;
4778 isnull = NS_UNKNOWN;
4779 aliased = AK_IMPTEMP;
4781 checked = CH_UNKNOWN;
4783 else if (reader_optCheckChar (s, '^'))
4785 defstate = SS_UNKNOWN;
4786 isnull = NS_UNKNOWN;
4787 aliased = AK_IMPTEMP;
4789 checked = CH_UNKNOWN;
4793 defstate = sstate_fromInt (reader_getInt (s));
4794 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4795 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4797 if (reader_optCheckChar (s, '&'))
4800 checked = CH_UNKNOWN;
4804 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4805 advanceField (s); checked = (chkind) (reader_getInt (s));
4810 name = reader_getStringWord (s);
4812 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4814 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4815 isnull, aliased, exp,
4816 checked, fileloc_copy (loc));
4829 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4830 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4831 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4832 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4833 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4834 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4835 advanceField (s); rtype = ctype_undump (s);
4837 name = reader_getStringWord (s);
4838 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4839 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
4840 aliased, exp, defstate, isnull,
4841 fileloc_copy (loc));
4858 stateClauseList specclauses = stateClauseList_undefined;
4859 warnClause warnclause = warnClause_undefined;
4861 if (reader_optCheckChar (s, '$'))
4863 defstate = SS_DEFINED;
4864 isnull = NS_UNKNOWN;
4865 exitCode = XK_UNKNOWN;
4867 nullPred = qual_createUnknown ();
4871 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4872 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4873 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4874 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4875 advanceField (s); nullPred = qual_undump (s);
4878 if (reader_optCheckChar (s, '$'))
4881 globs = globSet_undefined;
4883 mods = sRefSet_undefined;
4885 else if (reader_optCheckChar (s, '^'))
4888 globs = globSet_undefined;
4890 mods = sRefSet_undefined;
4894 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
4895 advanceField (s); globs = globSet_undump (s);
4896 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
4897 advanceField (s); mods = sRefSet_undump (s);
4900 if (reader_optCheckChar (s, '$'))
4907 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4908 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4911 advanceField (s); access = typeIdSet_undump (s);
4914 ** Optional clauses: Start with @<code>:
4917 while (reader_optCheckChar (s, '@'))
4919 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4921 reader_checkChar (s, ':');
4922 warnclause = warnClause_undump (s);
4924 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4926 reader_checkChar (s, ':');
4927 specclauses = stateClauseList_undump (s);
4935 advanceName (s); name = reader_getStringWord (s);
4937 ue = uentry_makeFunctionBase (name, ct, access,
4940 ak, exp, defstate, isnull,
4941 exitCode, specc, nullPred,
4944 fileloc_copy (loc));
4945 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4952 advanceField (s); access = typeIdSet_undump (s);
4953 advanceName (s); name = reader_getStringWord (s);
4955 ue = uentry_makeIterBase (name, access, ct,
4956 fileloc_copy (loc));
4963 advanceField (s); access = typeIdSet_undump (s);
4964 advanceName (s); name = reader_getStringWord (s);
4966 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4976 if (reader_optCheckChar (s, '$'))
4978 val = multiVal_undefined;
4979 access = typeIdSet_undefined;
4980 nullstate = NS_UNKNOWN;
4984 advanceField (s); val = multiVal_undump (s);
4985 advanceField (s); access = typeIdSet_undump (s);
4986 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
4989 advanceName (s); name = reader_getStringWord (s);
4991 ue = uentry_makeConstantBase (name, ct, access,
4992 nullstate, fileloc_copy (loc), val);
5001 advanceField (s); rtype = ctype_undump (s);
5002 advanceName (s); name = reader_getStringWord (s);
5003 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5007 llcontbuglit ("uentry_undump: invalid");
5008 ue = uentry_undefined;
5011 llcontbuglit ("uentry_undump: elips marker");
5012 ue = uentry_undefined;
5021 uentry_dump (uentry v)
5023 return (uentry_dumpAux (v, FALSE));
5027 uentry_dumpParam (uentry v)
5029 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5030 ("dump: %s", uentry_unparseFull (v)));
5032 return (uentry_dumpAux (v, TRUE));
5036 uentry_dumpAux (uentry v, bool isParam)
5038 llassert (uentry_isValid (v));
5039 llassert (!uentry_isGlobalMarker (v));
5041 DPRINTF (("Dump uentry: [%p]", v));
5042 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
5047 llcontbuglit ("uentry_dump: invalid entry");
5048 return cstring_undefined;
5050 return (message ("!."));
5054 vkind vk = v->info->var->kind;
5055 sstate dss = sRef_getDefState (v->sref);
5056 nstate nst = sRef_getNullState (v->sref);
5057 alkind alk = sRef_getAliasKind (v->sref);
5058 exkind exk = sRef_getExKind (v->sref);
5059 chkind chk = v->info->var->checked;
5061 DPRINTF (("Dumping var"));
5063 if (dss == SS_UNKNOWN
5064 && nst == NS_UNKNOWN
5065 && alk == AK_IMPTEMP
5066 && exk == XO_UNKNOWN
5067 && chk == CH_UNKNOWN)
5069 sdump = cstring_makeLiteral ("$");
5071 else if (dss == SS_DEFINED
5072 && nst == NS_UNKNOWN
5073 && alk == AK_IMPTEMP
5074 && exk == XO_UNKNOWN
5075 && chk == CH_UNKNOWN)
5077 sdump = cstring_makeLiteral ("&");
5079 else if (dss == SS_UNKNOWN
5080 && nst == NS_UNKNOWN
5081 && alk == AK_UNKNOWN
5082 && exk == XO_UNKNOWN
5083 && chk == CH_UNKNOWN)
5085 sdump = cstring_makeLiteral ("^");
5087 else if (exk == XO_UNKNOWN
5088 && chk == CH_UNKNOWN)
5090 sdump = message ("%d@%d@%d&",
5097 sdump = message ("%d@%d@%d@%d@%d",
5108 return (message ("%q|@%d|%q#%s",
5109 ctype_dump (v->utype),
5112 isParam ? cstring_undefined : v->uname));
5116 return (message ("%q|%q#%s",
5117 ctype_dump (v->utype),
5119 isParam ? cstring_undefined : v->uname));
5125 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5127 exkind_unparse (sRef_getExKind (v->sref)),
5128 ctype_unparse (v->utype), (int) v->utype));
5131 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5132 ctype_dump (v->utype),
5133 ynm_unparseCode (v->info->datatype->abs),
5134 ynm_unparseCode (v->info->datatype->mut),
5135 (int) sRef_getDefState (v->sref),
5136 (int) sRef_getNullState (v->sref),
5137 (int) sRef_getAliasKind (v->sref),
5138 (int) sRef_getExKind (v->sref),
5139 ctype_dump (v->info->datatype->type),
5143 cstring sdump, gdump, adump, xdump;
5144 alkind alk = sRef_getAliasKind (v->sref);
5145 exkind exk = sRef_getExKind (v->sref);
5147 if (sRef_getDefState (v->sref) == SS_DEFINED
5148 && !nstate_isKnown (sRef_getNullState (v->sref))
5149 && !exitkind_isKnown (v->info->fcn->exitCode)
5150 && v->info->fcn->specialCode == SPC_NONE
5151 && qual_isUnknown (v->info->fcn->nullPred))
5153 sdump = cstring_makeLiteral ("$");
5157 sdump = message ("@%d@%d@%d@%d@%x",
5158 (int) sRef_getDefState (v->sref),
5159 (int) sRef_getNullState (v->sref),
5160 (int) v->info->fcn->exitCode,
5161 (int) v->info->fcn->specialCode,
5162 qual_dump (v->info->fcn->nullPred));
5165 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5167 gdump = cstring_makeLiteral ("$");
5169 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5170 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5172 gdump = cstring_makeLiteral ("^");
5176 gdump = message ("@%s@%q@%s@%q",
5177 bool_dump (uentry_hasGlobs (v)),
5178 globSet_dump (uentry_getGlobs (v)),
5179 bool_dump (uentry_hasMods (v)),
5180 sRefSet_dump (uentry_getMods (v)));
5183 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5185 adump = cstring_makeLiteral ("$");
5189 adump = message ("@%d@%d", (int) alk, (int) exk);
5192 xdump = cstring_undefined;
5194 if (uentry_hasWarning (v))
5196 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
5199 if (uentry_hasStateClauseList (v))
5201 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
5204 return (message ("%q%q%q%q@%q%q#%s",
5205 ctype_dump (v->utype),
5209 typeIdSet_dump (uentry_accessType (v)),
5214 return (message ("%q@%q#%s",
5215 ctype_dump (v->utype),
5216 typeIdSet_dump (v->info->iter->access),
5219 return (message ("%q@%q#%s",
5220 ctype_dump (v->utype),
5221 typeIdSet_dump (uentry_accessType (v)),
5228 if (multiVal_isUnknown (uentry_getConstantValue (v))
5229 && typeIdSet_isEmpty (uentry_accessType (v))
5230 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5232 sdump = cstring_makeLiteral ("$");
5236 sdump = message ("@%q@%q@%d",
5237 multiVal_dump (uentry_getConstantValue (v)),
5238 typeIdSet_dump (uentry_accessType (v)),
5239 (int) sRef_getNullState (v->sref));
5242 return (message ("%q%q#%s",
5243 ctype_dump (v->utype),
5250 return (message ("%q@%q#%s",
5251 ctype_dump (v->utype),
5252 ctype_dump (v->info->datatype->type), v->uname));
5259 uentry_unparseAbbrev (uentry v)
5261 if (!uentry_isVariable (v))
5263 llcontbuglit ("uentry_unparseAbbrev: not variable");
5264 return uentry_unparse (v);
5267 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5271 uentry_unparse (uentry v)
5275 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5276 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5278 st = uentry_getName (v);
5280 if (cstring_isDefined (st))
5282 return (ctype_unparseDeclaration (v->utype, st));
5287 return (cstring_copy (ctype_unparse (v->utype)));
5292 uentry_unparseFull (uentry v)
5294 if (uentry_isUndefined (v))
5296 return (cstring_makeLiteral ("<undefined>"));
5302 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5303 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5304 ctype_unparse (v->utype),
5305 fileloc_unparse (uentry_whereSpecified (v)),
5306 fileloc_unparse (uentry_whereDeclared (v)),
5307 fileloc_unparse (uentry_whereDefined (v)));
5309 DPRINTF (("uentry: %s", res));
5311 if (uentry_isDatatype (v))
5313 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5316 (ctype_isDefined (v->info->datatype->type)
5317 ? v->info->datatype->type : ctype_unknown),
5318 ynm_unparse (v->info->datatype->mut),
5319 ynm_unparse (v->info->datatype->abs),
5320 sRef_unparseState (v->sref));
5322 else if (uentry_isFunction (v))
5324 res = message ("%q / sref: %q / mods: %q / "
5325 "globs: %q / clauses: %q / pre: %q / post: %q",
5327 sRef_unparseFull (v->sref),
5328 sRefSet_unparse (v->info->fcn->mods),
5329 globSet_unparse (v->info->fcn->globs),
5330 stateClauseList_unparse (v->info->fcn->specclauses),
5331 functionConstraint_unparse (v->info->fcn->preconditions),
5332 functionConstraint_unparse (v->info->fcn->postconditions));
5334 else if (uentry_isIter (v))
5336 res = message ("%q / sref: %q",
5338 sRef_unparseFull (v->sref));
5340 else if (uentry_isVariable (v))
5342 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5344 sRef_unparseFull (v->sref),
5345 (int) v->info->var->kind,
5346 (int) v->info->var->defstate,
5347 (int) v->info->var->nullstate,
5349 DPRINTF (("sref: [%p]", v->sref));
5350 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5351 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5353 else if (uentry_isConstant (v))
5355 res = message ("%q = %q",
5356 res, multiVal_unparse (uentry_getConstantValue (v)));
5360 res = message ("%q :: %q", res, uentry_unparse (v));
5367 bool uentry_hasAccessType (uentry e)
5369 if (uentry_isValid (e))
5374 return (!typeIdSet_isEmpty (e->info->iter->access));
5376 return (!typeIdSet_isEmpty (e->info->enditer->access));
5378 return (!typeIdSet_isEmpty (e->info->fcn->access));
5381 return (!typeIdSet_isEmpty (e->info->uconst->access));
5390 typeIdSet uentry_accessType (uentry e)
5392 if (uentry_isValid (e))
5397 return (e->info->iter->access);
5399 return (e->info->enditer->access);
5401 return (e->info->fcn->access);
5404 return (e->info->uconst->access);
5410 return typeIdSet_undefined;
5414 uentry_isVariable (uentry e)
5416 return (uentry_isVar (e));
5420 uentry_isSpecified (uentry e)
5422 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5426 uentry_isReallySpecified (uentry e)
5428 return (uentry_isValid (e)
5429 && fileloc_isRealSpec (e->whereSpecified));
5433 uentry_isVar (uentry e)
5435 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5439 uentry_isFakeTag (uentry e)
5441 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5445 uentry_isDatatype (uentry e)
5447 return (!uentry_isUndefined (e) &&
5448 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5449 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5453 uentry_setAbstract (uentry e)
5457 llassert (uentry_isDatatype (e)
5458 && (ynm_isMaybe (e->info->datatype->abs)));
5460 oldid = ctype_typeId (e->info->datatype->type);
5461 e->info->datatype->abs = YES;
5462 e->info->datatype->type = ctype_createAbstract (oldid);
5466 uentry_setConcrete (uentry e)
5468 llassert (uentry_isDatatype (e)
5469 && (ynm_isMaybe (e->info->datatype->abs)));
5471 e->info->datatype->abs = NO;
5475 uentry_isAbstractDatatype (uentry e)
5477 return (uentry_isDatatype (e)
5478 && (ynm_isOn (e->info->datatype->abs)));
5482 uentry_isMaybeAbstract (uentry e)
5484 return (uentry_isDatatype (e)
5485 && (ynm_isMaybe (e->info->datatype->abs)));
5489 uentry_isMutableDatatype (uentry e)
5491 bool res = uentry_isDatatype (e)
5492 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5498 uentry_isRefCountedDatatype (uentry e)
5500 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5504 uentry_isParam (uentry u)
5506 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5507 || u->info->var->kind == VKYIELDPARAM));
5511 uentry_isExpandedMacro (uentry u)
5513 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5517 uentry_isSefParam (uentry u)
5519 return (uentry_isVariable (u)
5520 && (u->info->var->kind == VKSEFPARAM
5521 || u->info->var->kind == VKREFSEFPARAM
5522 || u->info->var->kind == VKSEFRETPARAM
5523 || u->info->var->kind == VKREFSEFRETPARAM));
5527 uentry_isRefParam (uentry u)
5529 return (uentry_isVariable (u)
5530 && (u->info->var->kind == VKREFPARAM
5531 || u->info->var->kind == VKREFYIELDPARAM
5532 || u->info->var->kind == VKREFSEFPARAM
5533 || u->info->var->kind == VKREFSEFRETPARAM));
5537 uentry_isAnyParam (uentry u)
5539 return (uentry_isVariable (u)
5540 && ((u->info->var->kind == VKPARAM)
5541 || (u->info->var->kind == VKSEFPARAM)
5542 || (u->info->var->kind == VKYIELDPARAM)
5543 || (u->info->var->kind == VKRETPARAM)
5544 || (u->info->var->kind == VKSEFRETPARAM)));
5548 uentry_getDefState (uentry u)
5550 if (uentry_isValid (u))
5552 return (sRef_getDefState (u->sref));
5556 return (SS_UNKNOWN);
5561 uentry_isOut (uentry u)
5563 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5564 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5568 uentry_isPartial (uentry u)
5570 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5571 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5575 uentry_isStateSpecial (uentry u)
5577 return ((uentry_isVariable (u)
5578 && (u->info->var->defstate == SS_SPECIAL))
5579 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5582 exitkind uentry_getExitCode (uentry ue)
5584 if (uentry_isFunction (ue))
5586 return ue->info->fcn->exitCode;
5594 qual uentry_nullPred (uentry u)
5596 llassert (uentry_isRealFunction (u));
5598 if (uentry_isFunction (u))
5600 return (u->info->fcn->nullPred);
5604 return qual_createUnknown ();
5609 ** Note for variables, this is checking the declared state, not the current state.
5613 uentry_possiblyNull (uentry u)
5615 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5616 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5620 uentry_getAliasKind (uentry u)
5622 if (uentry_isValid (u))
5624 return (sRef_getAliasKind (uentry_getSref (u)));
5633 uentry_getExpKind (uentry u)
5635 if (uentry_isValid (u))
5637 return (sRef_getExKind (uentry_getSref (u)));
5646 uentry_isIter (uentry e)
5648 return (!uentry_isUndefined (e) && e->ukind == KITER);
5652 uentry_isEndIter (uentry e)
5654 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5658 uentry_isRealFunction (uentry e)
5660 return (uentry_isFunction (e) ||
5661 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5665 uentry_hasName (uentry e)
5667 if (uentry_isValid (e))
5669 cstring s = e->uname;
5671 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5672 || uentry_isFakeTag (e)));
5681 ** Returns true for fake tags.
5682 ** This is used for dumping the library
5685 bool uentry_hasRealName (uentry e)
5687 return (uentry_isValid (e)
5688 && cstring_isNonEmpty (e->uname)
5689 && !uentry_isGlobalMarker (e));
5693 /*@observer@*/ globSet
5694 uentry_getGlobs (uentry l)
5696 if (uentry_isInvalid (l))
5698 return globSet_undefined;
5701 if (l->ukind != KFCN)
5703 if (l->ukind != KITER && l->ukind != KENDITER)
5705 if (l->ukind == KVAR)
5707 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5709 ekind_unparse (l->ukind)));
5713 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5715 ekind_unparse (l->ukind)));
5718 return globSet_undefined;
5721 return l->info->fcn->globs;
5724 /*@observer@*/ sRefSet
5725 uentry_getMods (uentry l)
5727 llassert (uentry_isValid (l));
5729 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5731 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5732 return sRefSet_undefined;
5735 return l->info->fcn->mods;
5739 uentry_getKind (uentry e)
5741 llassert (uentry_isValid (e));
5746 /*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5748 llassert (uentry_isEitherConstant (e));
5749 return (sRef_getValue (e->sref));
5752 /*@observer@*/ uentryList
5753 uentry_getParams (uentry l)
5755 if (uentry_isInvalid (l)) return uentryList_undefined;
5762 ctype ct = l->utype;
5764 if (ctype_isFunction (ct))
5766 return (ctype_argsFunction (ct));
5770 return uentryList_undefined;
5775 ctype ct = l->utype;
5777 llassert (ctype_isFunction (ct));
5778 return (ctype_argsFunction (ct));
5785 /*@observer@*/ cstring
5786 uentry_rawName (uentry e)
5788 if (uentry_isValid (e))
5794 return cstring_undefined;
5799 uentry_getOptName (uentry e)
5801 cstring s = uentry_getName (e);
5803 if (cstring_isDefined (s))
5805 s = cstring_appendChar (s, ' ');
5812 uentry_getName (uentry e)
5814 cstring ret = cstring_undefined;
5816 if (uentry_isValid (e))
5818 if (uentry_isAnyTag (e))
5820 ret = fixTagName (e->uname);
5822 else if (uentry_isAnyParam (e))
5824 ret = cstring_copy (fixParamName (e->uname));
5828 ret = cstring_copy (e->uname);
5835 cstring uentry_observeRealName (uentry e)
5837 cstring ret = cstring_undefined;
5839 if (uentry_isValid (e))
5841 if (uentry_isAnyTag (e))
5843 if (isFakeTag (e->uname))
5845 ret = cstring_undefined;
5849 ret = plainTagName (e->uname);
5852 else if (uentry_isAnyParam (e))
5854 ret = fixParamName (e->uname);
5865 cstring uentry_getRealName (uentry e)
5867 if (uentry_isValid (e))
5869 if (uentry_isAnyTag (e))
5871 return (cstring_undefined);
5878 return cstring_undefined;
5881 ctype uentry_getType (uentry e)
5883 if (uentry_isValid (e))
5889 return ctype_unknown;
5893 fileloc uentry_whereLast (uentry e)
5897 if (uentry_isInvalid (e))
5899 return fileloc_undefined;
5902 loc = e->whereDefined;
5904 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5909 loc = uentry_whereDeclared (e);
5911 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5916 loc = uentry_whereSpecified (e);
5920 fileloc uentry_whereEither (uentry e)
5922 if (uentry_isInvalid (e)) return fileloc_undefined;
5924 if (fileloc_isDefined (e->whereDefined)
5925 && !fileloc_isExternal (e->whereDefined))
5927 return e->whereDefined;
5929 else if (fileloc_isDefined (e->whereDeclared))
5931 return e->whereDeclared;
5935 return e->whereSpecified;
5939 fileloc uentry_whereSpecified (uentry e)
5941 if (uentry_isInvalid (e)) return fileloc_undefined;
5943 return (e->whereSpecified);
5946 fileloc uentry_whereDefined (uentry e)
5948 if (uentry_isInvalid (e)) return fileloc_undefined;
5950 return (e->whereDefined);
5953 fileloc uentry_whereDeclared (uentry e)
5955 if (uentry_isInvalid (e)) return fileloc_undefined;
5957 return (e->whereDeclared);
5960 /*@observer@*/ fileloc
5961 uentry_whereEarliest (uentry e)
5963 if (uentry_isInvalid (e)) return fileloc_undefined;
5965 if (fileloc_isDefined (e->whereSpecified))
5967 return (e->whereSpecified);
5969 else if (fileloc_isDefined (e->whereDeclared))
5971 return (e->whereDeclared);
5975 return e->whereDefined;
5980 uentry_setFunctionDefined (uentry e, fileloc loc)
5982 if (uentry_isValid (e))
5984 llassert (uentry_isFunction (e));
5986 if (fileloc_isUndefined (e->whereDeclared))
5988 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
5991 if (!fileloc_isDefined (e->whereDefined))
5993 e->whereDefined = fileloc_update (e->whereDefined, loc);
5999 uentry_setDeclDef (uentry e, fileloc f)
6001 uentry_setDeclared (e, f);
6003 if (!uentry_isFunction (e)
6004 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6006 uentry_setDefined (e, f);
6011 uentry_setDeclaredForce (uentry e, fileloc f)
6013 llassert (uentry_isValid (e));
6014 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6018 uentry_setDeclaredForceOnly (uentry e, fileloc f)
6020 llassert (uentry_isValid (e));
6021 fileloc_free (e->whereDeclared);
6022 e->whereDeclared = f;
6026 uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6030 llassert (uentry_isValid (e));
6031 oldloc = e->whereDeclared;
6033 if (fileloc_isDefined (oldloc))
6035 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6037 e->whereDeclared = f;
6038 fileloc_free (oldloc);
6047 e->whereDeclared = f;
6048 fileloc_free (oldloc);
6053 uentry_setDeclared (uentry e, fileloc f)
6057 llassert (uentry_isValid (e));
6058 oldloc = e->whereDeclared;
6060 if (fileloc_isDefined (oldloc))
6062 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6064 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6073 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6078 uentry_clearDefined (uentry e)
6080 if (uentry_isValid (e))
6082 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6087 uentry_setDefined (uentry e, fileloc f)
6091 llassert (uentry_isValid (e));
6092 oldloc = e->whereDefined;
6094 if (fileloc_isDefined (oldloc))
6096 if (fileloc_isLib (oldloc)
6097 || fileloc_isImport (oldloc)
6098 || fileloc_isBuiltin (oldloc)
6099 || fileloc_isPreproc (oldloc))
6101 e->whereDefined = fileloc_update (e->whereDefined, f);
6105 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6111 if (optgenerror (FLG_REDEF,
6112 message ("%s %q redefined",
6113 ekind_capName (e->ukind),
6114 uentry_getName (e)),
6117 llgenindentmsg (message ("Previous definition of %q",
6118 uentry_getName (e)),
6126 e->whereDefined = fileloc_update (e->whereDefined, f);
6131 uentry_isCodeDefined (uentry e)
6133 llassert (uentry_isValid (e));
6135 return (fileloc_isDefined (e->whereDefined));
6139 uentry_isDeclared (uentry e)
6141 if (uentry_isValid (e))
6143 return (fileloc_isDefined (e->whereDeclared));
6149 sRef uentry_getSref (uentry e)
6151 /* not true, used for functions too (but shouldn't be? */
6152 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6154 if (uentry_isInvalid (e)) return sRef_undefined;
6159 sRef uentry_getOrigSref (uentry e)
6161 /*@i523*/ /* evans 2001-09-09 - need to fix this
6162 if (uentry_isValid (e))
6164 if (uentry_isVariable (e))
6166 return e->info->var->origsref;
6170 sRef sr = sRef_copy (uentry_getSref (e));
6172 sRef_resetState (sr);
6173 sRef_clearDerived (sr);
6179 return sRef_undefined;
6183 if (uentry_isValid (e))
6185 sRef sr = sRef_copy (uentry_getSref (e));
6187 sRef_resetState (sr);
6188 sRef_clearDerived (sr);
6190 if (uentry_isVariable (e))
6192 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6193 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6200 return sRef_undefined;
6205 ** requires: uentry e is not in a hashed symbol table
6209 uentry_setName (uentry e, /*@only@*/ cstring n)
6211 llassert (uentry_isValid (e));
6213 cstring_free (e->uname);
6218 uentry_setType (uentry e, ctype t)
6220 if (uentry_isValid (e))
6223 sRef_setType (e->sref, t);
6228 uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6231 ctype rettype = ctype_unknown;
6233 llassert (uentry_isValid (ue));
6235 uentry_convertVarFunction (ue);
6236 llassert (uentry_isFunction (ue));
6238 rct = ctype_realType (ue->utype);
6240 if (ctype_isFunction (rct))
6242 rettype = ctype_getReturnType (rct);
6245 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6249 uentry_setRefParam (uentry e)
6251 if (!uentry_isVar (e))
6253 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6257 if (e->info->var->kind == VKSEFPARAM)
6259 e->info->var->kind = VKREFSEFPARAM;
6261 else if (e->info->var->kind == VKSEFRETPARAM)
6263 e->info->var->kind = VKREFSEFRETPARAM;
6265 else if (e->info->var->kind == VKYIELDPARAM)
6267 e->info->var->kind = VKREFYIELDPARAM;
6271 e->info->var->kind = VKREFPARAM;
6277 uentry_setParam (uentry e)
6279 if (!uentry_isVar (e))
6281 if (uentry_isElipsisMarker (e))
6287 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6294 if (e->info->var->kind == VKYIELDPARAM
6295 || e->info->var->kind == VKSEFPARAM
6296 || e->info->var->kind == VKSEFRETPARAM)
6302 e->info->var->kind = VKPARAM;
6306 e->uname = makeParam (e->uname);
6307 cstring_free (oldname);
6312 uentry_setSref (uentry e, sRef s)
6314 if (uentry_isValid (e))
6316 if (sRef_isValid (e->sref))
6318 sRef_mergeStateQuietReverse (e->sref, s);
6322 e->sref = sRef_saveCopy (s);
6328 uentry_getAbstractType (uentry e)
6330 llassert (uentry_isDatatype (e));
6333 ** This assertion removed.
6334 ** Okay to have undefined type, for system types
6336 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6337 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6342 if (ctype_isUndefined (e->info->datatype->type))
6344 return ctype_unknown;
6348 ** Sadly, a kludge...
6351 if (ctype_isUserBool (e->info->datatype->type)) {
6355 return e->info->datatype->type;
6358 ctype uentry_getRealType (uentry e)
6361 typeId uid = USYMIDINVALID;
6363 if (uentry_isInvalid (e))
6365 return ctype_unknown;
6368 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6370 if (uentry_isAnyTag (e))
6375 if (uentry_isAbstractType (e))
6377 ct = uentry_getAbstractType (e);
6379 if (ctype_isManifestBool (ct)) {
6383 llassert (ctype_isUA (ct));
6385 uid = ctype_typeId (ct);
6387 if (!context_hasAccess (uid))
6393 ct = uentry_getType (e);
6395 /* if (ctype_isUserBool (ct)) return ct; */
6397 if (ctype_isManifestBool (ct)) {
6401 if (ctype_isUA (ct))
6403 usymId iid = ctype_typeId (ct);
6405 if (usymId_equal (iid, uid))
6407 llcontbug (message ("uentry_getRealType: recursive type! %s",
6408 ctype_unparse (ct)));
6413 /* evs 2000-07-25: possible infinite recursion ? */
6414 uentry ue2 = usymtab_getTypeEntry (iid);
6418 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6419 return ctype_unknown;
6422 return uentry_getRealType (ue2);
6431 ctype uentry_getForceRealType (uentry e)
6434 typeId uid = USYMIDINVALID;
6436 if (uentry_isInvalid (e))
6438 return ctype_unknown;
6441 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6443 if (uentry_isAnyTag (e))
6448 if (uentry_isAbstractType (e))
6450 ct = uentry_getAbstractType (e);
6451 llassert (ctype_isUA (ct));
6453 uid = ctype_typeId (ct);
6454 /* no check for access! */
6457 ct = uentry_getType (e);
6459 /* evs 2000-07-25 */
6460 /* if (ctype_isUserBool (ct)) return ct; */
6462 if (ctype_isManifestBool (ct)) {
6466 if (ctype_isUA (ct))
6468 usymId iid = ctype_typeId (ct);
6470 if (usymId_equal (iid, uid))
6472 llcontbug (message ("uentry_getRealType: recursive type! %s",
6473 ctype_unparse (ct)));
6478 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6487 uentry uentry_nameCopy (cstring name, uentry e)
6489 uentry enew = uentry_alloc ();
6491 llassert (uentry_isValid (e));
6493 /* enew->shallowCopy = FALSE; */
6494 enew->ukind = e->ukind;
6496 enew->utype = e->utype;
6497 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6498 enew->whereDefined = fileloc_copy (e->whereDefined);
6499 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6500 enew->sref = sRef_copy (e->sref);
6501 enew->used = e->used;
6503 enew->isPrivate = e->isPrivate;
6504 enew->hasNameError = FALSE;
6506 enew->uses = filelocList_new ();
6507 enew->warn = warnClause_undefined;
6509 enew->storageclass = e->storageclass;
6510 enew->info = uinfo_copy (e->info, e->ukind);
6516 uentry_setDatatype (uentry e, usymId uid)
6518 llassert (uentry_isDatatype (e));
6520 if (uentry_isAbstractType (e))
6522 e->info->datatype->type = ctype_createAbstract (uid);
6526 e->info->datatype->type = ctype_createUser (uid);
6531 uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6532 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6535 llassert (uentry_isValid (e));
6537 if (fileloc_isSpec (f) || fileloc_isImport (f))
6539 e->whereSpecified = f;
6540 e->whereDeclared = fileloc_undefined;
6541 e->whereDefined = fileloc_undefined;
6545 e->whereSpecified = fileloc_undefined;
6546 e->whereDeclared = f;
6547 e->whereDefined = fileloc_undefined;
6550 llassert (fileloc_storable (f));
6554 ucinfo_free (/*@only@*/ ucinfo u)
6560 uvinfo_free (/*@only@*/ uvinfo u)
6562 /*drl7x added 6/29/01 */
6563 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
6568 udinfo_free (/*@only@*/ udinfo u)
6574 ufinfo_free (/*@only@*/ ufinfo u)
6576 globSet_free (u->globs);
6577 sRefSet_free (u->mods);
6578 stateClauseList_free (u->specclauses);
6583 uiinfo_free (/*@only@*/ uiinfo u)
6589 ueinfo_free (/*@only@*/ ueinfo u)
6594 static /*@only@*/ ucinfo
6595 ucinfo_copy (ucinfo u)
6597 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
6598 ret->access = u->access;
6602 static /*@only@*/ uvinfo
6603 uvinfo_copy (uvinfo u)
6605 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6607 ret->kind = u->kind;
6608 ret->nullstate = u->nullstate;
6609 ret->defstate = u->defstate;
6610 ret->checked = u->checked;
6612 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6614 /* drl added 07-02-001 */
6615 /* copy null terminated information */
6617 if (u->bufinfo != NULL)
6619 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6620 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6621 ret->bufinfo->size = u->bufinfo->size;
6622 ret->bufinfo->len = u->bufinfo->len;
6627 ret->bufinfo = NULL;
6633 static /*@only@*/ udinfo
6634 udinfo_copy (udinfo u)
6636 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6640 ret->type = u->type;
6645 static /*@only@*/ ufinfo
6646 ufinfo_copy (ufinfo u)
6648 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6650 ret->hasGlobs = u->hasGlobs;
6651 ret->hasMods = u->hasMods;
6652 ret->exitCode = u->exitCode;
6653 ret->specialCode = u->specialCode;
6654 ret->nullPred = u->nullPred;
6655 ret->access = u->access;
6656 ret->globs = globSet_newCopy (u->globs);
6657 ret->mods = sRefSet_newCopy (u->mods);
6658 ret->defparams = u->defparams;
6659 ret->specclauses = stateClauseList_copy (u->specclauses);
6661 ret->preconditions = functionConstraint_copy (u->preconditions);
6662 ret->postconditions = functionConstraint_copy (u->postconditions);
6667 static /*@only@*/ uiinfo
6668 uiinfo_copy (uiinfo u)
6670 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6672 ret->access = u->access;
6673 ret->globs = globSet_newCopy (u->globs);
6674 ret->mods = sRefSet_newCopy (u->mods);
6679 static /*@only@*/ ueinfo
6680 ueinfo_copy (ueinfo u)
6682 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6684 ret->access = u->access;
6689 uinfo_free (uinfo u, ekind kind)
6694 case KCONST: ucinfo_free (u->uconst); break;
6695 case KVAR: uvinfo_free (u->var); break;
6699 case KDATATYPE: udinfo_free (u->datatype); break;
6700 case KFCN: ufinfo_free (u->fcn); break;
6701 case KITER: uiinfo_free (u->iter); break;
6702 case KENDITER: ueinfo_free (u->enditer); break;
6703 case KELIPSMARKER: break;
6704 case KINVALID: break;
6710 static /*@only@*/ /*@null@*/ uinfo
6711 uinfo_copy (uinfo u, ekind kind)
6713 if (kind == KELIPSMARKER || kind == KINVALID)
6719 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6724 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6725 case KVAR: ret->var = uvinfo_copy (u->var); break;
6729 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6730 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6731 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6732 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6740 uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6742 filelocList_free (e->uses);
6743 cstring_free (e->uname);
6745 uinfo_free (e->info, e->ukind);
6747 fileloc_free (e->whereSpecified);
6748 fileloc_free (e->whereDefined);
6749 fileloc_free (e->whereDeclared);
6751 warnClause_free (e->warn);
6757 extern void uentry_markOwned (/*@owned@*/ uentry u)
6759 sfreeEventually (u);
6763 uentry_free (/*@only@*/ uentry e)
6765 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6767 uentry_reallyFree (e);
6772 ** For uentry's in the global or file scope
6776 uentry_freeComplete (/*@only@*/ uentry e)
6778 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6780 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
6781 /*@i@*/ sRef_free (e->sref);
6782 e->sref = sRef_undefined;
6783 uentry_reallyFree (e);
6788 ** requires old->kind != new->kind, old->uname = new->uname
6792 KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6794 llassert (uentry_isValid (old));
6795 llassert (uentry_isValid (unew));
6797 if (uentry_isEitherConstant (unew)
6798 && (fileloc_isPreproc (uentry_whereDeclared (old))
6799 || ctype_isUnknown (old->utype))
6800 && !uentry_isSpecified (old))
6808 if (!uentry_isDeclared (old))
6810 if (uentry_isSpecified (old))
6812 if (uentry_isSpecified (unew))
6814 llbuglit ("Respecification!");
6816 else if (uentry_isDeclared (unew))
6820 message ("%s %q inconsistently declared as %s: %t",
6821 ekind_capName (old->ukind),
6822 uentry_getName (unew),
6823 ekind_unparseLong (unew->ukind),
6825 uentry_whereDeclared (unew)))
6827 uentry_showWhereLast (old);
6839 message ("%s %q inconsistently declared as %s: %t",
6840 ekind_capName (old->ukind),
6841 uentry_getName (unew),
6842 ekind_unparseLong (unew->ukind),
6844 uentry_whereDeclared (unew)))
6846 uentry_showWhereLast (old);
6852 llassert (uentry_isDeclared (unew));
6856 message ("%s %q inconsistently redeclared as %s",
6857 ekind_capName (old->ukind),
6858 uentry_getName (unew),
6859 ekind_unparseLong (unew->ukind)),
6860 uentry_whereDeclared (unew)))
6862 uentry_showWhereLast (old);
6868 uentry_updateInto (old, unew);
6872 ** def is the definition of spec, modifies spec
6874 ** reports any inconsistencies
6875 ** returns the summary of all available information
6876 ** if spec and def are inconsistent, def is returned
6880 uentry_showWhereLast (uentry spec)
6882 if (uentry_isValid (spec))
6884 if (fileloc_isDefined (spec->whereDefined)
6885 && !fileloc_isLib (spec->whereDefined)
6886 && !fileloc_isPreproc (spec->whereDefined))
6888 llgenindentmsg (message ("Previous definition of %q: %t",
6889 uentry_getName (spec),
6890 uentry_getType (spec)),
6891 uentry_whereDefined (spec));
6893 else if (uentry_isDeclared (spec))
6895 llgenindentmsg (message ("Previous declaration of %q: %t",
6896 uentry_getName (spec),
6897 uentry_getType (spec)),
6898 uentry_whereDeclared (spec));
6900 else if (uentry_isSpecified (spec))
6902 if (uentry_hasName (spec))
6904 llgenindentmsg (message ("Specification of %q: %t",
6905 uentry_getName (spec),
6906 uentry_getType (spec)),
6907 uentry_whereSpecified (spec));
6911 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6912 uentry_whereSpecified (spec));
6917 /* nothing to show */
6923 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6925 fileloc loc = uentry_whereDefined (ce);
6927 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6929 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
6933 loc = uentry_whereSpecified (ce);
6935 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
6937 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
6942 void uentry_showWhereLastExtra (uentry spec, cstring extra)
6944 if (uentry_isDeclared (spec))
6946 llgenindentmsg (message ("Previous declaration of %q: %q",
6947 uentry_getName (spec), extra),
6948 uentry_whereDeclared (spec));
6950 else if (uentry_isSpecified (spec))
6952 llgenindentmsg (message ("Specification of %q: %q",
6953 uentry_getName (spec), extra),
6954 uentry_whereSpecified (spec));
6958 cstring_free (extra);
6963 uentry_showWhereDeclared (uentry spec)
6965 if (uentry_isDeclared (spec))
6967 if (uentry_hasName (spec))
6969 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
6970 uentry_whereDeclared (spec));
6974 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
6977 else if (uentry_isSpecified (spec))
6979 if (uentry_hasName (spec))
6981 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
6982 uentry_whereSpecified (spec));
6986 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
6991 /* nothing to show */
6997 uentry_showWhereAny (uentry spec)
6999 if (uentry_isDeclared (spec))
7001 if (uentry_hasName (spec))
7003 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7004 uentry_whereDeclared (spec));
7008 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7011 else if (uentry_isSpecified (spec))
7013 if (uentry_hasName (spec))
7015 llgenindentmsg (message ("Specification of %q",
7016 uentry_getName (spec)),
7017 uentry_whereSpecified (spec));
7021 llgenindentmsg (cstring_makeLiteral ("Specification"),
7022 uentry_whereSpecified (spec));
7025 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7027 if (uentry_hasName (spec))
7029 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7030 uentry_whereDefined (spec));
7034 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7039 /* nothing to show */
7044 uentry_showWhereDefined (uentry spec)
7046 if (uentry_isCodeDefined (spec))
7048 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7049 uentry_whereDefined (spec));
7054 uentry_showWhereLastPlain (uentry spec)
7056 if (uentry_isDeclared (spec))
7058 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7059 uentry_whereDeclared (spec));
7061 else if (uentry_isSpecified (spec))
7063 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7064 uentry_whereSpecified (spec));
7072 uentry_showWhereLastVal (uentry spec, cstring val)
7074 if (uentry_isDeclared (spec))
7076 llgenindentmsg (message ("Previous declaration of %q: %s",
7077 uentry_getName (spec), val),
7078 uentry_whereDeclared (spec));
7080 else if (uentry_isSpecified (spec))
7082 llgenindentmsg (message ("Specification of %q: %s",
7083 uentry_getName (spec), val),
7084 uentry_whereSpecified (spec));
7092 uentry_showWhereSpecified (uentry spec)
7094 if (uentry_isSpecified (spec))
7096 if (uentry_hasName (spec))
7098 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7099 uentry_whereSpecified (spec));
7103 llgenindentmsg (cstring_makeLiteral ("Specification"),
7104 uentry_whereSpecified (spec));
7107 else if (uentry_isDeclared (spec))
7109 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7110 uentry_whereDeclared (spec));
7114 /* nothing to show */
7119 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7121 if (uentry_isSpecified (spec))
7123 if (uentry_hasName (spec))
7125 llgenindentmsg (message ("Specification of %q: %q",
7126 uentry_getName (spec), s),
7127 uentry_whereSpecified (spec));
7131 llgenindentmsg (message ("Specification: %q", s),
7132 uentry_whereSpecified (spec));
7135 else if (uentry_isDeclared (spec))
7137 llgenindentmsg (message ("Declaration of %q: %q",
7138 uentry_getName (spec), s),
7139 uentry_whereDeclared (spec));
7143 llgenindentmsg (message ("Previous: %q", s),
7144 uentry_whereLast (spec));
7153 checkStructConformance (uentry old, uentry unew)
7156 uentryList fold, fnew;
7159 ** requires: types of old and new are structs or unions
7162 llassert (uentry_isValid (old));
7163 llassert (uentry_isValid (unew));
7165 oldr = ctype_realType (old->utype);
7166 fold = ctype_getFields (oldr);
7168 newr = ctype_realType (unew->utype);
7169 fnew = ctype_getFields (newr);
7171 if (!uentryList_matchFields (fold, fnew))
7173 if (fileloc_equal (uentry_whereLast (old),
7174 uentry_whereLast (unew)))
7182 message ("%q %q %rdeclared with fields { %q }, %s "
7183 "with fields { %q }",
7184 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7185 uentry_getName (old),
7186 uentry_isDeclared (old),
7187 uentryList_unparseAbbrev (fnew),
7188 uentry_specOrDefName (old),
7189 uentryList_unparseAbbrev (fold)),
7190 uentry_whereDeclared (unew)))
7192 uentry_showWhereLastPlain (old);
7193 uentryList_showFieldDifference (fold, fnew);
7197 old->utype = unew->utype;
7202 checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7205 ** requires old and new are enums
7208 ctype rold = ctype_realType (old->utype);
7209 ctype rnew = ctype_realType (unew->utype);
7210 enumNameList eold = ctype_elist (rold);
7211 enumNameList enew = ctype_elist (rnew);
7213 if (!enumNameList_match (eold, enew))
7217 message ("Enum %q declared with members { %q } but "
7218 "specified with members { %q }",
7219 uentry_getName (old),
7220 enumNameList_unparse (enew),
7221 enumNameList_unparse (eold)),
7222 uentry_whereDeclared (unew)))
7224 uentry_showWhereSpecified (old);
7225 old->utype = unew->utype;
7231 ** either oldCurrent or newCurrent may be undefined!
7235 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7236 uentry unew, uentry newCurrent, ctype newType,
7239 bool hasError = FALSE;
7241 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7243 if (uentry_hasName (newCurrent))
7245 hasError = optgenerror
7247 message ("Parameter %d, %q, of function %q has inconsistent type: "
7248 "declared %t, %s %t",
7249 paramno + 1, uentry_getName (newCurrent),
7250 uentry_getName (unew),
7251 newType, uentry_specOrDefName (old), oldType),
7252 uentry_whereDeclared (newCurrent));
7256 hasError = optgenerror
7258 message ("Parameter %d of function %q has inconsistent type: "
7259 "declared %t, %s %t",
7260 paramno + 1, uentry_getName (unew),
7261 newType, uentry_specOrDefName (old), oldType),
7262 uentry_whereDeclared (newCurrent));
7264 DPRINTF (("type: %s / %s",
7265 ctype_unparse (newType),
7266 ctype_unparse (ctype_realType (newType))));
7271 if (uentry_isDeclared (unew))
7273 hasError = optgenerror
7275 message ("Parameter %d of function %s has inconsistent type: "
7276 "declared %t, %s %t",
7277 paramno + 1, unew->uname,
7278 newType, uentry_specOrDefName (old), oldType),
7279 uentry_whereDeclared (unew));
7283 hasError = optgenerror
7285 message ("Parameter %d of function %s has inconsistent type: "
7286 "declared %t, %s %t",
7287 paramno + 1, unew->uname,
7288 newType, uentry_specOrDefName (old), oldType),
7289 uentry_whereDeclared (unew));
7295 DPRINTF (("Here: %s / %s",
7296 uentry_unparseFull (oldCurrent),
7297 uentry_unparseFull (newCurrent)));
7299 if (!uentry_isUndefined (oldCurrent))
7301 if (!uentry_isUndefined (newCurrent)
7302 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7304 uentry_showWhereLast (oldCurrent);
7308 uentry_showWhereLastPlain (old);
7311 uentry_setType (oldCurrent, newType);
7315 uentry_showWhereLastPlain (old);
7321 nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7325 message ("Function %s %rdeclared with %d arg%&, %s with %d",
7327 uentry_isDeclared (old),
7328 uentryList_size (uentry_getParams (unew)),
7329 uentry_specOrDefName (old),
7330 uentryList_size (uentry_getParams (old))),
7331 uentry_whereDeclared (unew)))
7333 uentry_showWhereLastPlain (old);
7338 returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7342 message ("Function %s inconsistently %rdeclared to return %t",
7344 uentry_isDeclared (old),
7345 ctype_getReturnType (unew->utype)),
7346 uentry_whereDeclared (unew)))
7348 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
7352 static cstring paramStorageName (uentry ue)
7354 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7357 static cstring fcnErrName (uentry ue)
7359 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7362 extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7364 if (uentry_isVar (ue))
7366 return (checkedName (ue->info->var->checked));
7370 return (cstring_makeLiteralTemp ("<checked invalid>"));
7374 static cstring checkedName (chkind checked)
7378 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7379 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7380 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7381 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7382 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7388 void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7393 if (uentry_isVar (unew))
7395 llassert (uentry_isVar (old));
7397 oldState = old->info->var->nullstate;
7398 newState = unew->info->var->nullstate;
7402 oldState = sRef_getNullState (old->sref);
7403 newState = sRef_getNullState (unew->sref);
7406 if (oldState == NS_ABSNULL)
7408 if (uentry_isVar (old))
7410 old->info->var->nullstate = newState;
7413 sRef_mergeNullState (old->sref, newState);
7415 else if (newState == NS_UNKNOWN)
7417 if (completeConform && newState != oldState
7418 && uentry_isReallySpecified (old))
7422 message ("%s %q specified as %s, but declared without %s qualifier",
7423 ekind_capName (unew->ukind),
7424 uentry_getName (unew),
7425 nstate_unparse (oldState),
7426 nstate_unparse (oldState)),
7427 uentry_whereDeclared (unew)))
7429 uentry_showWhereSpecified (old);
7433 if (uentry_isVar (unew))
7435 unew->info->var->nullstate = oldState;
7438 sRef_mergeNullState (unew->sref, oldState);
7440 else if (newState == NS_POSNULL)
7442 if (oldState == NS_MNOTNULL
7443 && (ctype_isUA (unew->utype)
7444 || (uentry_isFunction (unew)
7445 && ctype_isUA (ctype_getReturnType (unew->utype)))))
7447 if (uentry_isVar (unew))
7449 unew->info->var->nullstate = oldState;
7452 sRef_mergeNullState (unew->sref, oldState);
7456 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7457 || oldState == NS_UNKNOWN)
7464 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7466 uentry_ekindName (unew),
7467 uentry_getName (unew),
7468 uentry_isDeclared (old),
7470 uentry_specOrDefName (old),
7471 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7472 uentry_whereDeclared (unew)))
7474 uentry_showWhereSpecified (old);
7479 if (uentry_isVar (old))
7481 old->info->var->nullstate = newState;
7484 sRef_mergeNullState (old->sref, newState);
7487 else if (newState == NS_MNOTNULL)
7489 if (oldState != NS_MNOTNULL)
7495 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7496 "%s without notnull qualifier",
7497 uentry_ekindName (unew),
7498 uentry_getName (unew),
7499 uentry_isDeclared (old),
7501 uentry_specOrDefName (old)),
7502 uentry_whereDeclared (unew)))
7504 uentry_showWhereSpecified (old);
7508 if (uentry_isVar (old))
7510 old->info->var->nullstate = newState;
7513 sRef_mergeNullState (old->sref, newState);
7518 if (uentry_isVar (unew))
7520 unew->info->var->nullstate = oldState;
7523 sRef_mergeNullState (unew->sref, oldState);
7528 void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7529 bool mustConform, bool completeConform)
7535 if (uentry_isVar (old) && uentry_isVar (unew))
7537 oldState = old->info->var->defstate;
7538 newState = unew->info->var->defstate;
7543 oldState = sRef_getDefState (old->sref);
7544 newState = sRef_getDefState (unew->sref);
7547 if (newState != oldState
7548 && newState != SS_UNKNOWN
7549 && newState != SS_DEFINED)
7555 message ("%s %q inconsistently %rdeclared %s %s %s, "
7557 uentry_ekindName (unew),
7558 uentry_getName (unew),
7559 uentry_isDeclared (old),
7561 sstate_unparse (newState),
7562 paramStorageName (unew),
7563 uentry_specOrDefName (old),
7565 sstate_unparse (oldState),
7566 paramStorageName (unew)),
7567 uentry_whereDeclared (unew)))
7569 uentry_showWhereSpecified (old);
7573 if (vars) old->info->var->defstate = newState;
7574 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7579 && (newState != oldState) && (oldState != SS_DEFINED)
7580 && uentry_isReallySpecified (old))
7584 message ("%s %q specified as %s, but declared without %s qualifier",
7585 ekind_capName (unew->ukind),
7586 uentry_getName (unew),
7587 sstate_unparse (oldState),
7588 sstate_unparse (oldState)),
7589 uentry_whereDeclared (unew)))
7591 uentry_showWhereSpecified (old);
7595 if (vars) unew->info->var->defstate = oldState;
7596 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7601 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7602 bool mustConform, bool completeConform)
7607 oldKind = sRef_getAliasKind (old->sref);
7608 newKind = sRef_getAliasKind (unew->sref);
7610 if (alkind_isImplicit (newKind)
7611 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7613 if (completeConform && !alkind_equal (newKind, oldKind)
7614 && uentry_isReallySpecified (old))
7618 message ("%s %q specified as %s, but declared without "
7619 "explicit alias qualifier",
7620 ekind_capName (unew->ukind),
7621 uentry_getName (unew),
7622 alkind_unparse (oldKind)),
7623 uentry_whereDeclared (unew)))
7625 uentry_showWhereSpecified (old);
7630 ** This really shouldn't be necessary, but it is!
7631 ** Function params (?) use new here.
7634 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7638 if (alkind_isKnown (newKind))
7640 if (!alkind_equal (oldKind, newKind))
7642 if (alkind_isKnown (oldKind))
7647 message ("%s %q inconsistently %rdeclared %s %s storage, "
7649 uentry_ekindName (unew),
7650 uentry_getName (unew),
7651 uentry_isDeclared (old),
7653 alkind_unparse (newKind),
7654 uentry_specOrDefName (old),
7655 alkind_unparse (oldKind)),
7656 uentry_whereDeclared (unew)))
7658 uentry_showWhereSpecified (old);
7660 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7661 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
7662 sRef_setAliasKind (old->sref, AK_ERROR,
7663 uentry_whereDeclared (unew));
7667 sRef_setAliasKind (old->sref, newKind,
7668 uentry_whereDeclared (unew));
7673 if (!(alkind_isImplicit (newKind)))
7676 !uentry_isFunction (unew) &&
7679 message ("%s %q inconsistently %rdeclared %s %s storage, "
7680 "implicitly %s as temp storage",
7681 uentry_ekindName (unew),
7682 uentry_getName (unew),
7683 uentry_isDeclared (old),
7685 alkind_unparse (newKind),
7686 uentry_specOrDefName (old)),
7687 uentry_whereDeclared (unew)))
7689 uentry_showWhereSpecified (old);
7693 sRef_setAliasKind (old->sref, newKind,
7694 uentry_whereDeclared (unew));
7696 else /* newKind is temp or refcounted */
7703 else /* newKind unknown */
7710 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7711 bool mustConform, bool completeConform)
7716 oldKind = sRef_getExKind (old->sref);
7717 newKind = sRef_getExKind (unew->sref);
7719 if (exkind_isKnown (newKind))
7721 if (oldKind != newKind)
7723 if (exkind_isKnown (oldKind))
7728 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7729 uentry_ekindName (unew),
7730 uentry_getName (unew),
7731 uentry_isDeclared (old),
7733 exkind_unparse (newKind),
7734 uentry_specOrDefName (old),
7735 exkind_unparse (oldKind)),
7736 uentry_whereDeclared (unew)))
7738 uentry_showWhereSpecified (old);
7741 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7748 message ("%s %q inconsistently %rdeclared %s %s, "
7749 "implicitly %s without exposure qualifier",
7750 uentry_ekindName (unew),
7751 uentry_getName (unew),
7752 uentry_isDeclared (old),
7754 exkind_unparse (newKind),
7755 uentry_specOrDefName (old)),
7756 uentry_whereDeclared (unew)))
7758 uentry_showWhereSpecified (old);
7761 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7767 if (completeConform && exkind_isKnown (oldKind)
7768 && uentry_isReallySpecified (old))
7772 message ("%s %q specified as %s, but declared without "
7773 "exposure qualifier",
7774 ekind_capName (unew->ukind),
7775 uentry_getName (unew),
7776 exkind_unparse (oldKind)),
7777 uentry_whereDeclared (unew)))
7779 uentry_showWhereSpecified (old);
7783 /* yes, this is necessary! (if its a param) */
7784 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7789 checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7790 bool mustConform, /*@unused@*/ bool completeConform)
7792 valueTable newvals = sRef_getValueTable (unew->sref);
7794 if (valueTable_isDefined (newvals))
7796 DPRINTF (("Check meta state: %s -> %s",
7797 uentry_unparseFull (old),
7798 uentry_unparseFull (unew)));
7800 DPRINTF (("Check meta state refs: %s -> %s",
7801 sRef_unparseFull (old->sref),
7802 sRef_unparseFull (unew->sref)));
7804 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7807 ** Copy the new values into the old ref
7810 valueTable_elements (newvals, key, newval)
7812 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7813 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7815 llassert (metaStateInfo_isDefined (msinfo));
7817 if (stateValue_isUndefined (oldval))
7819 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7823 if (stateValue_isError (oldval))
7825 if (!stateValue_isError (newval))
7827 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7831 ; /* No change necessary. */
7836 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7838 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7844 if (!stateValue_isError (newval)
7845 && !stateValue_isImplicit (newval))
7847 if (uentry_hasName (unew)
7848 || !sRef_isParam (uentry_getSref (unew)))
7853 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7854 uentry_ekindName (unew),
7855 uentry_getName (unew),
7856 uentry_isDeclared (old),
7858 stateValue_unparseValue (newval, msinfo),
7859 uentry_specOrDefName (old),
7860 stateValue_unparseValue (oldval, msinfo)),
7861 uentry_whereDeclared (unew)))
7863 uentry_showWhereSpecified (old);
7871 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7872 uentry_ekindName (unew),
7873 sRef_getParam (uentry_getSref (unew)),
7874 uentry_isDeclared (old),
7876 stateValue_unparseValue (newval, msinfo),
7877 uentry_specOrDefName (old),
7878 stateValue_unparseValue (oldval, msinfo)),
7879 uentry_whereDeclared (unew)))
7881 uentry_showWhereSpecified (old);
7887 DPRINTF (("Updating!"));
7888 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7892 DPRINTF (("Values match"));
7896 } end_valueTable_elements ;
7901 uentry_checkStateConformance (/*@notnull@*/ uentry old,
7902 /*@notnull@*/ uentry unew,
7903 bool mustConform, bool completeConform)
7905 checkDefState (old, unew, mustConform, completeConform);
7906 checkNullState (old, unew, mustConform, completeConform);
7907 checkAliasState (old, unew, mustConform, completeConform);
7908 checkExpState (old, unew, mustConform, completeConform);
7909 checkMetaState (old, unew, mustConform, completeConform);
7911 sRef_storeState (old->sref);
7912 sRef_storeState (unew->sref);
7916 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7918 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7923 llassert (uentry_isVar (old));
7924 llassert (uentry_isVar (unew));
7926 if (cstring_isEmpty (old->uname))
7928 cstring_free (old->uname);
7929 old->uname = cstring_copy (unew->uname);
7932 if (unew->info->var->kind == VKRETPARAM
7933 || unew->info->var->kind == VKSEFRETPARAM)
7935 if (old->info->var->kind != VKRETPARAM
7936 && old->info->var->kind != VKSEFRETPARAM)
7940 message ("Parameter %q inconsistently %rdeclared as "
7941 "returned parameter",
7942 uentry_getName (unew),
7943 uentry_isDeclared (old)),
7944 uentry_whereDeclared (unew)))
7946 uentry_showWhereSpecified (old);
7947 old->info->var->kind = unew->info->var->kind;
7953 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
7955 if (old->info->var->kind != VKSEFPARAM
7956 && old->info->var->kind != VKSEFRETPARAM)
7960 message ("Parameter %qinconsistently %rdeclared as "
7962 uentry_getOptName (unew),
7963 uentry_isDeclared (old)),
7964 uentry_whereDeclared (unew)))
7966 uentry_showWhereSpecified (old);
7967 old->info->var->kind = unew->info->var->kind;
7972 if (old->info->var->kind == VKSPEC)
7974 old->info->var->kind = unew->info->var->kind;
7978 unew->info->var->kind = old->info->var->kind;
7981 if (unew->info->var->checked != CH_UNKNOWN
7982 && unew->info->var->checked != old->info->var->checked)
7984 if (old->info->var->checked == CH_UNKNOWN
7985 && !fileloc_isUser (uentry_whereLast (old)))
7993 message ("Variable %q inconsistently %rdeclared as "
7994 "%s parameter (was %s)",
7995 uentry_getName (unew),
7996 uentry_isDeclared (old),
7997 checkedName (unew->info->var->checked),
7998 checkedName (old->info->var->checked)),
7999 uentry_whereDeclared (unew)))
8001 uentry_showWhereSpecified (old);
8005 old->info->var->checked = unew->info->var->checked;
8010 && (old->info->var->checked != CH_UNKNOWN)
8011 && uentry_isReallySpecified (old))
8015 message ("%s %q specified as %s, but declared without %s qualifier",
8016 ekind_capName (unew->ukind),
8017 uentry_getName (unew),
8018 checkedName (old->info->var->checked),
8019 checkedName (old->info->var->checked)),
8020 uentry_whereDeclared (unew)))
8022 uentry_showWhereSpecified (old);
8026 unew->info->var->checked = old->info->var->checked;
8029 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8032 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8034 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8039 llassert (uentry_isVar (u1));
8040 llassert (uentry_isVar (u2));
8042 if (u1->info->var->kind != u2->info->var->kind) {
8043 if (u1->info->var->kind == VKSEFRETPARAM) {
8044 if (u2->info->var->kind == VKRETPARAM) {
8047 message ("Function types are inconsistent. Parameter %d is "
8048 "sef parameter, but non-sef parameter in "
8049 "assigned function: %s",
8050 paramno, exprNode_unparse (e)),
8052 } else if (u2->info->var->kind == VKSEFPARAM) {
8055 message ("Function types are inconsistent. Parameter %d is "
8056 "returns parameter, but non-returns parameter in "
8057 "assigned function: %s",
8058 paramno, exprNode_unparse (e)),
8063 message ("Function types are inconsistent. Parameter %d is "
8064 "sef returns parameter, but non-sef returns parameter in "
8065 "assigned function: %s",
8066 paramno, exprNode_unparse (e)),
8069 } else if (u1->info->var->kind == VKRETPARAM) {
8072 message ("Function types are inconsistent. Parameter %d is "
8073 "returns parameter, but non-returns parameter in "
8074 "assigned function: %s",
8075 paramno, exprNode_unparse (e)),
8077 } else if (u1->info->var->kind == VKSEFPARAM) {
8080 message ("Function types are inconsistent. Parameter %d is "
8081 "sef parameter, but non-sef parameter in "
8082 "assigned function: %s",
8083 paramno, exprNode_unparse (e)),
8086 if (u2->info->var->kind == VKSEFRETPARAM) {
8089 message ("Function types are inconsistent. Parameter %d is "
8090 "normal parameter, but sef returns parameter in "
8091 "assigned function: %s",
8092 paramno, exprNode_unparse (e)),
8094 } else if (u2->info->var->kind == VKSEFPARAM) {
8097 message ("Function types are inconsistent. Parameter %d is "
8098 "normal parameter, but sef parameter in "
8099 "assigned function: %s",
8100 paramno, exprNode_unparse (e)),
8102 } else if (u2->info->var->kind == VKRETPARAM) {
8105 message ("Function types are inconsistent. Parameter %d is "
8106 "normal parameter, but returns parameter in "
8107 "assigned function: %s",
8108 paramno, exprNode_unparse (e)),
8116 if (u1->info->var->defstate != u2->info->var->defstate)
8120 message ("Function types are inconsistent. Parameter %d is "
8121 "%s, but %s in assigned function: %s",
8123 sstate_unparse (u1->info->var->defstate),
8124 sstate_unparse (u2->info->var->defstate),
8125 exprNode_unparse (e)),
8129 if (u1->info->var->nullstate != u2->info->var->nullstate)
8133 message ("Function types are inconsistent. Parameter %d is "
8134 "%s, but %s in assigned function: %s",
8136 nstate_unparse (u1->info->var->nullstate),
8137 nstate_unparse (u2->info->var->nullstate),
8138 exprNode_unparse (e)),
8142 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8146 message ("Function types are inconsistent. Parameter %d is "
8147 "%s, but %s in assigned function: %s",
8149 alkind_unparse (sRef_getAliasKind (u1->sref)),
8150 alkind_unparse (sRef_getAliasKind (u2->sref)),
8151 exprNode_unparse (e)),
8155 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8159 message ("Function types are inconsistent. Parameter %d is "
8160 "%s, but %s in assigned function: %s",
8162 exkind_unparse (sRef_getExKind (u1->sref)),
8163 exkind_unparse (sRef_getExKind (u2->sref)),
8164 exprNode_unparse (e)),
8170 checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8171 /*@notnull@*/ uentry unew,
8172 bool mustConform, /*@unused@*/ bool completeConform)
8174 uentryList oldParams = uentry_getParams (old);
8175 uentryList newParams = uentry_getParams (unew);
8176 ctype newType = unew->utype;
8177 ctype oldType = old->utype;
8178 ctype oldRetType = ctype_unknown;
8179 ctype newRetType = ctype_unknown;
8181 DPRINTF (("Function conform: %s ==> %s",
8182 uentry_unparseFull (old),
8183 uentry_unparseFull (unew)));
8185 if (uentry_isForward (old))
8187 mustConform = FALSE;
8188 uentry_updateInto (old, unew);
8193 ** check return values
8196 if (ctype_isKnown (oldType))
8198 llassert (ctype_isFunction (oldType));
8200 oldRetType = ctype_getReturnType (oldType);
8203 if (ctype_isKnown (newType))
8205 llassert (ctype_isFunction (newType));
8207 newRetType = ctype_getReturnType (newType);
8210 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8211 && !ctype_matchDef (newRetType, oldRetType))
8213 if (mustConform) returnValueError (old, unew);
8217 if (ctype_isConj (newRetType))
8219 if (ctype_isConj (oldRetType))
8221 if (!ctype_sameAltTypes (newRetType, oldRetType))
8225 message ("Function %q inconsistently %rdeclared to "
8226 "return alternate types %s "
8227 "(types match, but alternates are not identical, "
8228 "so checking may not be correct)",
8229 uentry_getName (unew),
8230 uentry_isDeclared (old),
8231 ctype_unparse (newRetType)),
8232 uentry_whereDeclared (unew)))
8234 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8240 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8245 DPRINTF (("Before state: %s",
8246 uentry_unparseFull (old)));
8247 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8248 DPRINTF (("After state: %s",
8249 uentry_unparseFull (old)));
8251 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8253 if (exitkind_isKnown (unew->info->fcn->exitCode))
8257 message ("Function %q inconsistently %rdeclared using %s",
8258 uentry_getName (unew),
8259 uentry_isDeclared (old),
8260 exitkind_unparse (unew->info->fcn->exitCode)),
8261 uentry_whereDeclared (unew)))
8263 uentry_showWhereSpecified (old);
8268 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8272 if (!qual_isUnknown (unew->info->fcn->nullPred))
8274 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
8278 message ("Function %q inconsistently %rdeclared using %s",
8279 uentry_getName (unew),
8280 uentry_isDeclared (old),
8281 qual_unparse (unew->info->fcn->nullPred)),
8282 uentry_whereDeclared (unew)))
8284 uentry_showWhereSpecified (old);
8290 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8293 if (unew->info->fcn->specialCode != SPC_NONE)
8295 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8299 message ("Function %q inconsistently %rdeclared using %s",
8300 uentry_getName (unew),
8301 uentry_isDeclared (old),
8302 specCode_unparse (unew->info->fcn->specialCode)),
8303 uentry_whereDeclared (unew)))
8305 uentry_showWhereSpecified (old);
8311 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8318 if (!uentryList_sameObject (oldParams, newParams)
8319 && (!uentryList_isMissingParams (oldParams)))
8321 if (!uentryList_isMissingParams (newParams))
8324 int nparams = uentryList_size (oldParams);
8325 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8327 if (nparams != uentryList_size (newParams))
8329 nargsError (old, unew);
8332 if (uentryList_size (newParams) < nparams)
8334 nparams = uentryList_size (newParams);
8337 while (paramno < nparams)
8339 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8340 uentry newCurrent = uentryList_getN (newParams, paramno);
8341 ctype oldCurrentType = uentry_getType (oldCurrent);
8342 ctype newCurrentType = uentry_getType (newCurrent);
8344 llassert (uentry_isValid (oldCurrent)
8345 && uentry_isValid (newCurrent));
8347 if (!uentry_isElipsisMarker (oldCurrent)
8348 && !uentry_isElipsisMarker (newCurrent))
8350 checkVarConformance (oldCurrent, newCurrent,
8351 mustConform, completeConform);
8356 if (uentry_hasName (oldCurrent)
8357 && uentry_hasName (newCurrent))
8359 cstring oldname = uentry_getName (oldCurrent);
8360 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8362 cstring nname = uentry_getName (newCurrent);
8365 if (cstring_isDefined (pfx)
8366 && cstring_equalPrefix (oldname, pfx))
8368 oname = cstring_suffix (oldname, cstring_length (pfx));
8373 /*@-branchstate@*/ } /*@=branchstate@*/
8375 if (cstring_isDefined (pfx)
8376 && cstring_equalPrefix (nname, pfx))
8378 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8383 /*@-branchstate@*/ } /*@=branchstate@*/
8385 if (!cstring_equal (oname, nnamefix))
8388 (FLG_DECLPARAMMATCH,
8389 message ("Definition parameter name %s does not match "
8390 "name of corresponding parameter in "
8393 uentry_whereLast (newCurrent)))
8395 uentry_showWhereLastPlain (oldCurrent);
8399 cstring_free (oldname);
8400 cstring_free (nname);
8404 if (!ctype_match (oldCurrentType, newCurrentType))
8406 paramTypeError (old, oldCurrent, oldCurrentType,
8407 unew, newCurrent, newCurrentType, paramno);
8411 if (ctype_isMissingParamsMarker (newCurrentType)
8412 || ctype_isElips (newCurrentType)
8413 || ctype_isMissingParamsMarker (oldCurrentType)
8414 || ctype_isElips (oldCurrentType))
8420 if (ctype_isConj (newCurrentType))
8422 if (ctype_isConj (oldCurrentType))
8424 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8428 message ("Parameter %q inconsistently %rdeclared with "
8429 "alternate types %s "
8430 "(types match, but alternates are not identical, "
8431 "so checking may not be correct)",
8432 uentry_getName (newCurrent),
8433 uentry_isDeclared (oldCurrent),
8434 ctype_unparse (newCurrentType)),
8435 uentry_whereDeclared (unew)))
8437 uentry_showWhereLastVal (oldCurrent,
8438 ctype_unparse (oldCurrentType));
8446 message ("Parameter %q inconsistently %rdeclared with "
8447 "alternate types %s",
8448 uentry_getName (newCurrent),
8449 uentry_isDeclared (oldCurrent),
8450 ctype_unparse (newCurrentType)),
8451 uentry_whereDeclared (unew)))
8453 uentry_showWhereLastVal (oldCurrent,
8454 ctype_unparse (oldCurrentType));
8461 if (ctype_isConj (oldCurrentType))
8463 uentry_setType (newCurrent, oldCurrentType);
8471 ** Forgot this! detected by lclint:
8472 ** uentry.c:1257,15: Suspected infinite loop
8478 if (!uentryList_isMissingParams (newParams))
8480 if (ctype_isConj (oldRetType))
8482 old->utype = ctype_makeFunction (oldRetType,
8483 uentryList_copy (newParams));
8487 old->utype = unew->utype;
8491 checkGlobalsConformance (old, unew, mustConform, completeConform);
8492 checkModifiesConformance (old, unew, mustConform, completeConform);
8494 DPRINTF (("Before list: %s",
8495 uentry_unparseFull (old)));
8497 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
8499 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
8504 message ("Function %q redeclared using special clauses (can only "
8505 "be used in first declaration)",
8506 uentry_getName (unew)),
8507 uentry_whereDeclared (unew)))
8509 uentry_showWhereLast (old);
8513 /*@i23 need checking @*/
8515 old->info->fcn->specclauses = unew->info->fcn->specclauses;
8519 /*@i43 should be able to append? @*/
8521 stateClauseList_checkEqual (old, unew);
8522 stateClauseList_free (unew->info->fcn->specclauses);
8523 unew->info->fcn->specclauses = stateClauseList_undefined;
8526 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
8529 if (fileloc_isUndefined (old->whereDeclared))
8531 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8533 else if (fileloc_isUndefined (unew->whereDeclared))
8535 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8544 uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8548 llassert (uentry_isValid (ue));
8549 llassert (uentry_isEitherConstant (ue));
8551 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8552 uval = uentry_getConstantValue (ue);
8554 if (multiVal_isDefined (uval))
8556 if (multiVal_isDefined (m))
8558 if (!multiVal_equiv (uval, m))
8562 message ("%s %q defined with inconsistent value: %q",
8563 ekind_capName (ue->ukind),
8564 uentry_getName (ue),
8565 multiVal_unparse (m)),
8568 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8576 uentry_setConstantValue (ue, m);
8581 bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8584 bool typeError = FALSE;
8586 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8588 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8592 DPRINTF (("Check struct conformance: %s / %s",
8593 uentry_unparseFull (old),
8594 uentry_unparseFull (unew)));
8595 checkStructConformance (old, unew);
8600 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8602 llbug (message ("struct tags: bad types: %t / %t",
8603 old->utype, unew->utype));
8607 else if (uentry_isEnumTag (old))
8609 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8611 if (mustConform) checkEnumConformance (old, unew);
8615 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8617 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8618 ctype_unparse (unew->utype)));
8622 else if (!ctype_match (old->utype, unew->utype))
8624 DPRINTF (("Type mismatch: %s / %s",
8625 ctype_unparse (old->utype),
8626 ctype_unparse (unew->utype)));
8628 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8630 ctype realt = ctype_realType (unew->utype);
8632 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8634 unew->utype = ctype_bool;
8640 typeError = optgenerror
8642 message ("%q defined as %s", uentry_getName (old),
8643 ctype_unparse (realt)),
8644 uentry_whereDeclared (unew));
8652 ctype oldr = ctype_realType (old->utype);
8653 ctype newr = ctype_realType (unew->utype);
8655 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8657 checkStructConformance (old, unew);
8659 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8661 checkStructConformance (old, unew);
8663 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8665 checkEnumConformance (old, unew);
8667 else if (uentry_isConstant (old)
8668 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8670 /* okay...for now! (should check the type is reset later... */
8674 DPRINTF (("YABA!"));
8677 message ("%s %q %rdeclared with inconsistent type: %t",
8678 ekind_capName (unew->ukind),
8679 uentry_getName (unew),
8680 uentry_isDeclared (old),
8682 uentry_whereDeclared (unew)))
8684 uentry_showWhereLast (old);
8700 uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8701 /*@notnull@*/ uentry unew,
8702 bool mustConform, bool completeConform)
8704 if (ctype_isDefined (unew->info->datatype->type))
8707 ** bool is hard coded here, since it is built into LCL.
8708 ** For now, we're stuck with LCL's types.
8711 if (ctype_isDirectBool (old->utype) &&
8712 cstring_equalLit (unew->uname, "bool"))
8714 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8715 evs 2000-07-25: removed
8717 unew->utype = ctype_bool;
8720 if (ctype_isUnknown (old->info->datatype->type))
8722 old->info->datatype->type = unew->info->datatype->type;
8726 DPRINTF (("Old: %s / New: %s",
8727 uentry_unparseFull (old),
8728 uentry_unparseFull (unew)));
8729 DPRINTF (("Types: %s / %s",
8730 ctype_unparse (old->info->datatype->type),
8731 ctype_unparse (unew->info->datatype->type)));
8733 if (ctype_matchDef (old->info->datatype->type,
8734 unew->info->datatype->type))
8743 ("Type %q %s with inconsistent type: %t",
8744 uentry_getName (unew),
8745 uentry_reDefDecl (old, unew),
8746 unew->info->datatype->type),
8747 uentry_whereDeclared (unew)))
8749 uentry_showWhereLastExtra
8750 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8753 old->info->datatype->type = unew->info->datatype->type;
8758 if (unew->info->datatype->abs != MAYBE)
8760 if (ynm_isOff (old->info->datatype->abs)
8761 && ynm_isOn (unew->info->datatype->abs))
8763 if (!ctype_isDirectBool (old->utype))
8768 ("Datatype %q inconsistently %rdeclared as abstract type",
8769 uentry_getName (unew),
8770 uentry_isDeclared (old)),
8771 uentry_whereDeclared (unew)))
8773 uentry_showWhereLastPlain (old);
8777 else if (ynm_isOn (old->info->datatype->abs)
8778 && ynm_isOff (unew->info->datatype->abs))
8780 if (!ctype_isDirectBool (old->utype))
8785 ("Datatype %q inconsistently %rdeclared as concrete type",
8786 uentry_getName (unew),
8787 uentry_isDeclared (old)),
8788 uentry_whereDeclared (unew)))
8790 uentry_showWhereLastPlain (old);
8801 if (ynm_isOn (old->info->datatype->abs))
8803 old->sref = unew->sref;
8804 unew->info->datatype->mut = old->info->datatype->mut;
8807 && uentry_isReallySpecified (old))
8812 ("Datatype %q specified as abstract, "
8813 "but abstract annotation not used in declaration",
8814 uentry_getName (unew)),
8815 uentry_whereDeclared (unew)))
8817 uentry_showWhereLastPlain (old);
8823 unew->info->datatype->abs = old->info->datatype->abs;
8825 if (ynm_isMaybe (unew->info->datatype->mut))
8827 if (completeConform && ynm_isOff (old->info->datatype->mut)
8828 && uentry_isReallySpecified (old))
8833 ("Datatype %q specified as immutable, "
8834 "but immutable annotation not used in declaration",
8835 uentry_getName (unew)),
8836 uentry_whereDeclared (unew)))
8838 uentry_showWhereLastPlain (old);
8842 unew->info->datatype->mut = old->info->datatype->mut;
8844 else if (ynm_isMaybe (old->info->datatype->mut))
8846 old->info->datatype->mut = unew->info->datatype->mut;
8850 if (ynm_isOn (old->info->datatype->abs))
8852 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8856 message ("Datatype %q inconsistently %rdeclared as immutable",
8857 uentry_getName (unew),
8858 uentry_isDeclared (old)),
8859 uentry_whereDeclared (unew)))
8861 uentry_showWhereLastPlain (old);
8866 if (ynm_isOff (old->info->datatype->mut)
8867 && ynm_isOn (unew->info->datatype->mut))
8871 message ("Datatype %q inconsistently %rdeclared as mutable",
8872 uentry_getName (unew),
8873 uentry_isDeclared (old)),
8874 uentry_whereDeclared (unew)))
8876 uentry_showWhereLastPlain (old);
8881 old->info->datatype->mut = unew->info->datatype->mut;
8884 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8888 uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8889 /*@notnull@*/ uentry unew,
8891 /*@unused@*/ bool completeConform)
8893 multiVal oldval = uentry_getConstantValue (old);
8894 multiVal newval = uentry_getConstantValue (unew);
8896 if (multiVal_isDefined (oldval))
8898 if (multiVal_isDefined (newval))
8900 if (!multiVal_equiv (oldval, newval))
8905 message ("%s %q %rdeclared with inconsistent value: %q",
8906 ekind_capName (unew->ukind),
8907 uentry_getName (unew),
8908 uentry_isDeclared (old),
8909 multiVal_unparse (newval)),
8910 uentry_whereDeclared (unew)))
8912 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
8916 uentry_setConstantValue (unew, multiVal_copy (oldval));
8925 uentry_setConstantValue (old, multiVal_copy (newval));
8930 uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8931 /*@notnull@*/ uentry unew, bool mustConform,
8932 bool completeConform)
8934 bool typeError = FALSE;
8935 bool fcnConformance = FALSE;
8937 if (!ekind_equal (unew->ukind, old->ukind))
8940 ** okay, only if one is a function and the other is
8941 ** a variable of type function.
8944 if (unew->ukind == KENUMCONST
8945 && old->ukind == KCONST)
8947 old->ukind = KENUMCONST;
8951 if (unew->ukind == KFCN
8952 && old->ukind == KCONST
8953 && ctype_isUnknown (old->utype))
8956 ** When a function is defined with an unparam macro
8959 uentry_updateInto (old, unew);
8963 if (uentry_isExpandedMacro (old)
8964 && uentry_isEitherConstant (unew))
8966 uentry_updateInto (old, unew);
8970 if (uentry_isEndIter (unew))
8972 if (ctype_isUnknown (old->utype))
8974 if (!uentry_isSpecified (old)
8975 && uentry_isCodeDefined (unew))
8977 if (!fileloc_withinLines (uentry_whereDefined (old),
8978 uentry_whereDeclared (unew), 2))
8979 { /* bogus! will give errors if there is too much whitespace */
8983 ("Iterator finalized name %q does not match name in "
8984 "previous iter declaration (should be end_%q). This iter "
8985 "is declared at %q",
8986 uentry_getName (unew),
8987 uentry_getName (old),
8988 fileloc_unparse (uentry_whereDefined (old))),
8989 uentry_whereDeclared (old));
8993 uentry_updateInto (old, unew);
8998 KindConformanceError (old, unew, mustConform);
9002 if (uentry_isFunction (unew))
9004 if (uentry_isVariable (old))
9006 if (!ctype_isUnknown (old->utype))
9008 if (ctype_isFunction (old->utype))
9010 uentry_makeVarFunction (old);
9011 checkFunctionConformance (old, unew, mustConform,
9013 fcnConformance = TRUE;
9017 KindConformanceError (old, unew, mustConform);
9022 if (uentry_isExpandedMacro (old))
9024 if (fileloc_isUndefined (unew->whereDefined))
9026 unew->whereDefined = fileloc_update (unew->whereDefined,
9030 uentry_updateInto (old, unew);
9031 old->used = unew->used = TRUE;
9036 /* undeclared identifier */
9037 old->utype = unew->utype;
9038 uentry_makeVarFunction (old);
9039 checkFunctionConformance (old, unew, FALSE, FALSE);
9040 fcnConformance = TRUE;
9046 KindConformanceError (old, unew, mustConform);
9049 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9051 if (!ctype_isUnknown (unew->utype))
9053 if (ctype_isFunction (unew->utype))
9055 uentry_makeVarFunction (unew);
9056 checkFunctionConformance (old, unew, mustConform, completeConform);
9057 fcnConformance = TRUE;
9061 KindConformanceError (old, unew, mustConform);
9066 KindConformanceError (old, unew, mustConform);
9071 KindConformanceError (old, unew, mustConform);
9077 ** check parameter lists for functions
9078 ** (before type errors, to get better messages
9081 if (uentry_isFunction (old))
9083 checkFunctionConformance (old, unew, mustConform, completeConform);
9084 fcnConformance = TRUE;
9088 if (!ctype_isUndefined (old->utype))
9090 typeError = checkTypeConformance (old, unew, mustConform);
9097 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9099 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9102 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9104 DPRINTF (("Check datatype: %s / %s",
9105 uentry_unparseFull (old),
9106 uentry_unparseFull (unew)));
9108 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9111 if (uentry_isVariable (old) && uentry_isVariable (unew))
9114 !ctype_matchDef (old->utype, unew->utype))
9119 ("Variable %q %s with inconsistent type (arrays and pointers are "
9120 "not identical in variable declarations): %t",
9121 uentry_getName (unew),
9122 uentry_reDefDecl (old, unew),
9124 uentry_whereDeclared (unew)))
9126 uentry_showWhereLast (old);
9129 ** Avoid repeated errors.
9132 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9134 old->whereDefined = fileloc_update (old->whereDefined,
9142 checkVarConformance (old, unew, mustConform, completeConform);
9147 /* old->utype = unew->utype; */
9151 if (ctype_isConj (old->utype))
9153 if (ctype_isConj (unew->utype))
9155 if (!ctype_sameAltTypes (old->utype, unew->utype))
9159 message ("%s %q inconsistently %rdeclared with "
9160 "alternate types %s "
9161 "(types match, but alternates are not identical, "
9162 "so checking may not be correct)",
9163 ekind_capName (uentry_getKind (old)),
9164 uentry_getName (unew),
9165 uentry_isDeclared (old),
9166 ctype_unparse (unew->utype)),
9167 uentry_whereDeclared (unew)))
9169 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9173 old->utype = unew->utype;
9180 if (ctype_isUnknown (old->utype))
9182 old->utype = unew->utype;
9187 if (unew->ukind == old->ukind)
9190 unew->info = uinfo_copy (old->info, old->ukind);
9193 sRef_storeState (old->sref);
9194 sRef_storeState (unew->sref);
9197 static void uentry_mergeConstraints (uentry spec, uentry def)
9199 if (uentry_isFunction (def))
9201 DPRINTF (("Here: %s / %s",
9202 uentry_unparseFull (spec),
9203 uentry_unparseFull (def)));
9204 /* evans 2001-07-21 */
9205 llassert (uentry_isFunction (spec));
9207 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9209 if (fileloc_isXHFile (uentry_whereLast (def)))
9211 llassert (uentry_isFunction (spec));
9212 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9213 def->info->fcn->preconditions);
9215 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9221 /* Check if the constraints are identical */
9226 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9227 uentry_getName (spec),
9228 functionConstraint_unparse (spec->info->fcn->preconditions)),
9229 uentry_whereLast (def)))
9231 uentry_showWhereSpecified (spec);
9234 functionConstraint_free (spec->info->fcn->preconditions);
9235 spec->info->fcn->preconditions = def->info->fcn->preconditions;
9238 def->info->fcn->preconditions = functionConstraint_undefined;
9241 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9243 if (fileloc_isXHFile (uentry_whereLast (def)))
9245 llassert (uentry_isFunction (spec));
9246 DPRINTF (("Post: %s /++/ %s",
9247 functionConstraint_unparse (spec->info->fcn->postconditions),
9248 functionConstraint_unparse (def->info->fcn->postconditions)));
9249 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9250 def->info->fcn->postconditions);
9251 def->info->fcn->postconditions = functionConstraint_undefined;
9252 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9259 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9260 uentry_getName (spec),
9261 functionConstraint_unparse (spec->info->fcn->postconditions)),
9262 uentry_whereLast (def)))
9264 uentry_showWhereSpecified (spec);
9267 functionConstraint_free (spec->info->fcn->postconditions);
9268 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9269 def->info->fcn->postconditions = functionConstraint_undefined;
9276 ** modifies spec to reflect def, reports any inconsistencies
9280 uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9282 llassert (uentry_isValid (spec));
9283 llassert (uentry_isValid (def));
9284 llassert (cstring_equal (spec->uname, def->uname));
9286 if (uentry_isFunction (def))
9288 if (uentry_isConstant (spec))
9290 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9291 uentry_makeConstantFunction (spec);
9295 uentry_convertVarFunction (spec);
9298 llassert (uentry_isFunction (spec));
9301 DPRINTF (("Merge entries: %s / %s",
9302 uentry_unparseFull (spec),
9303 uentry_unparseFull (def)));
9305 uentry_mergeConstraints (spec, def);
9307 uentry_checkConformance (spec, def, TRUE,
9308 context_getFlag (FLG_NEEDSPEC));
9310 DPRINTF (("Merge entries after conform: %s / %s",
9311 uentry_unparseFull (spec),
9312 uentry_unparseFull (def)));
9314 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9317 ** okay, declarations conform. Propagate extra information.
9320 uentry_setDefined (spec, uentry_whereDefined (def));
9321 uentry_setDeclared (spec, uentry_whereDeclared (def));
9323 if (uentry_isStatic (def))
9327 message ("%s %q specified, but declared as static",
9328 ekind_capName (def->ukind),
9329 uentry_getName (def)),
9330 uentry_whereDeclared (def)))
9332 uentry_showWhereSpecified (spec);
9337 spec->storageclass = def->storageclass;
9340 sRef_storeState (spec->sref);
9342 spec->used = def->used || spec->used;
9343 spec->hasNameError |= def->hasNameError;
9347 if (!spec->hasNameError)
9349 uentry_checkName (spec);
9358 ** Can't generate function redeclaration errors when the
9359 ** entries are merged, since we don't yet know if its the
9360 ** definition of the function.
9364 uentry_clearDecl (void)
9366 posRedeclared = uentry_undefined;
9367 fileloc_free (posLoc);
9368 posLoc = fileloc_undefined;
9372 uentry_checkDecl (void)
9374 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
9376 llassert (fileloc_isDefined (posLoc));
9378 if (uentry_isCodeDefined (posRedeclared))
9380 if (optgenerror (FLG_REDECL,
9381 message ("%s %q declared after definition",
9382 ekind_capName (posRedeclared->ukind),
9383 uentry_getName (posRedeclared)),
9386 llgenindentmsg (message ("Definition of %q",
9387 uentry_getName (posRedeclared)),
9388 posRedeclared->whereDeclared);
9393 if (optgenerror (FLG_REDECL,
9394 message ("%s %q declared more than once",
9395 ekind_capName (posRedeclared->ukind),
9396 uentry_getName (posRedeclared)),
9399 llgenindentmsg (message ("Previous declaration of %q",
9400 uentry_getName (posRedeclared)),
9401 posRedeclared->whereDeclared);
9406 fileloc_free (posLoc);
9407 posLoc = fileloc_undefined;
9408 posRedeclared = uentry_undefined;
9412 ** Redefinition of old as unew.
9413 ** modifies old to reflect unew, reports any inconsistencies
9417 uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9419 fileloc olddef = uentry_whereDeclared (old);
9420 fileloc unewdef = uentry_whereDeclared (unew);
9424 DPRINTF (("uentry merge: %s / %s",
9425 uentry_unparseFull (old),
9426 uentry_unparseFull (unew)));
9429 fileloc_isUndefined (olddef)
9430 && fileloc_isDefined (uentry_whereDefined (old))
9431 && !uentry_isExpandedMacro (old);
9433 if (!context_getFlag (FLG_INCONDEFSLIB)
9434 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9436 mustConform = FALSE;
9443 llassert (uentry_isValid (old));
9444 llassert (uentry_isValid (unew));
9445 llassert (cstring_equal (old->uname, unew->uname));
9447 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9449 if (uentry_isConstant (old))
9451 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9452 uentry_makeConstantFunction (old);
9456 uentry_convertVarFunction (old);
9459 llassert (uentry_isFunction (old));
9462 DPRINTF (("uentry merge: %s / %s",
9463 uentry_unparseFull (old),
9464 uentry_unparseFull (unew)));
9466 if (uentry_isExtern (unew))
9468 uentry_setUsed (old, unewdef);
9472 ** should check old one was extern!
9475 if (uentry_isStatic (old))
9477 if (!(uentry_isStatic (unew)))
9481 message ("%s %q shadows static declaration",
9482 ekind_capName (unew->ukind),
9483 uentry_getName (unew)),
9486 uentry_showWhereLast (old);
9491 uentry_setDeclDef (old, unewdef);
9494 else if (uentry_isStatic (unew))
9496 uentry_setDeclDef (old, unewdef);
9498 else if (uentry_isExtern (old))
9500 uentry_setDeclared (old, unewdef);
9504 if (!uentry_isExtern (unew)
9505 && !uentry_isForward (old)
9506 && !fileloc_equal (olddef, unewdef)
9507 && !fileloc_isUndefined (olddef)
9508 && !fileloc_isUndefined (unewdef)
9509 && !fileloc_isBuiltin (olddef)
9510 && !fileloc_isBuiltin (unewdef)
9511 && !uentry_isYield (old)
9512 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9514 if (uentry_isVariable (old) || uentry_isVariable (unew))
9516 ; /* will report redeclaration error later */
9520 if (fileloc_isDefined (uentry_whereDefined (old)))
9524 message ("%s %q defined more than once",
9525 ekind_capName (unew->ukind),
9526 uentry_getName (unew)),
9527 uentry_whereLast (unew)))
9530 (message ("Previous definition of %q",
9531 uentry_getName (old)),
9532 uentry_whereLast (old));
9535 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9537 uentry_updateInto (old, unew);
9538 old->sref = sRef_saveCopy (old->sref);
9546 if (fileloc_isLib (olddef)
9547 || fileloc_isUndefined (olddef)
9548 || fileloc_isImport (olddef))
9550 if (uentry_isExtern (unew))
9552 if (uentry_isExtern (old)
9553 || (fileloc_isDefined (uentry_whereDeclared (old))
9554 && (!fileloc_equal (uentry_whereDeclared (old),
9555 uentry_whereDefined (old)))))
9559 message ("%s %q declared more than once",
9560 ekind_capName (unew->ukind),
9561 uentry_getName (unew)),
9562 unew->whereDeclared))
9565 (message ("Previous declaration of %q",
9566 uentry_getName (old)),
9567 old->whereDeclared);
9571 uentry_setExtern (old);
9575 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
9581 DPRINTF (("uentry merge: %s / %s",
9582 uentry_unparseFull (old),
9583 uentry_unparseFull (unew)));
9585 uentry_mergeConstraints (old, unew);
9586 DPRINTF (("uentry merge: %s / %s",
9587 uentry_unparseFull (old),
9588 uentry_unparseFull (unew)));
9590 uentry_checkConformance (old, unew, mustConform, FALSE);
9591 DPRINTF (("uentry merge: %s / %s",
9592 uentry_unparseFull (old),
9593 uentry_unparseFull (unew)));
9595 old->used = old->used || unew->used;
9596 old->uses = filelocList_append (old->uses, unew->uses);
9597 unew->uses = filelocList_undefined;
9599 sRef_storeState (old->sref);
9600 sRef_storeState (unew->sref);
9604 old->whereDefined = fileloc_update (old->whereDefined,
9608 DPRINTF (("here: %s", uentry_unparseFull (old)));
9611 ** No redeclaration errors for functions here, since we
9612 ** don't know if this is the definition of the function.
9615 if (fileloc_isUser (old->whereDeclared)
9616 && fileloc_isUser (unew->whereDeclared)
9617 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9618 && !fileloc_isDefined (unew->whereDefined))
9620 if (uentry_isFunction (old))
9622 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9623 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9627 if (optgenerror (FLG_REDECL,
9628 message ("%s %q declared more than once",
9629 ekind_capName (unew->ukind),
9630 uentry_getName (unew)),
9631 unew->whereDeclared))
9633 llgenindentmsg (message ("Previous declaration of %q",
9634 uentry_getName (old)),
9635 old->whereDeclared);
9640 if (fileloc_isUndefined (old->whereDefined))
9642 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9646 if (!context_processingMacros ()
9647 && fileloc_isUser (old->whereDefined)
9648 && fileloc_isUser (unew->whereDefined)
9649 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9651 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9653 if (uentry_isVariable (unew)
9654 && uentry_isExtern (unew))
9656 if (optgenerror (FLG_REDECL,
9657 message ("%s %q declared after definition",
9658 ekind_capName (unew->ukind),
9659 uentry_getName (unew)),
9660 unew->whereDeclared))
9662 llgenindentmsg (message ("Definition of %q",
9663 uentry_getName (old)),
9669 if (optgenerror (FLG_REDEF,
9670 message ("%s %q redefined",
9671 ekind_capName (unew->ukind),
9672 uentry_getName (unew)),
9673 unew->whereDefined))
9675 llgenindentmsg (message ("Previous definition of %q",
9676 uentry_getName (old)),
9684 if (uentry_isExternal (unew))
9686 old->whereDefined = fileloc_createExternal ();
9689 if (unew->hasNameError)
9691 old->hasNameError = TRUE;
9696 if (!old->hasNameError)
9698 uentry_checkName (old);
9701 DPRINTF (("After: %s", uentry_unparseFull (old)));
9702 llassert (!ctype_isUndefined (old->utype));
9706 uentry_copyState (uentry res, uentry other)
9708 llassert (uentry_isValid (res));
9709 llassert (uentry_isValid (other));
9711 res->used = other->used;
9713 res->info->var->kind = other->info->var->kind;
9714 res->info->var->defstate = other->info->var->defstate;
9715 res->info->var->nullstate = other->info->var->nullstate;
9716 res->info->var->checked = other->info->var->checked;
9718 sRef_copyState (res->sref, other->sref);
9722 uentry_sameKind (uentry u1, uentry u2)
9724 if (uentry_isValid (u1) && uentry_isValid (u2))
9726 if (uentry_isVar (u1) && uentry_isVar (u2))
9728 ctype c1 = u1->utype;
9729 ctype c2 = u2->utype;
9731 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9734 ** both functions, or both not functions
9737 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9741 return ((u1->ukind == u2->ukind));
9748 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
9750 ekind okind = unew->ukind;
9751 llassert (uentry_isValid (unew));
9752 llassert (uentry_isValid (old));
9754 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9756 unew->ukind = old->ukind;
9757 llassert (cstring_equal (unew->uname, old->uname));
9758 unew->utype = old->utype;
9760 if (fileloc_isDefined (unew->whereSpecified)
9761 && !fileloc_isDefined (old->whereSpecified))
9763 ; /* Keep the old value */
9767 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9768 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9771 if (fileloc_isDefined (unew->whereDefined)
9772 && !fileloc_isDefined (old->whereDefined))
9774 ; /* Keep the old value */
9778 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9779 unew->whereDefined = fileloc_copy (old->whereDefined);
9782 if (fileloc_isDefined (unew->whereDeclared)
9783 && !fileloc_isDefined (old->whereDeclared))
9785 ; /* Keep the old value */
9789 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9790 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9793 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9795 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9796 unew->used = old->used;
9798 unew->isPrivate = old->isPrivate;
9799 unew->hasNameError = old->hasNameError;
9800 unew->uses = filelocList_append (unew->uses, old->uses);
9801 old->uses = filelocList_undefined;
9803 unew->storageclass = old->storageclass;
9804 uinfo_free (unew->info, okind);
9805 unew->info = uinfo_copy (old->info, old->ukind);
9810 uentry_copy (uentry e)
9812 if (uentry_isValid (e))
9814 uentry enew = uentry_alloc ();
9815 DPRINTF (("copy: %s", uentry_unparseFull (e)));
9816 enew->ukind = e->ukind;
9817 enew->uname = cstring_copy (e->uname);
9818 enew->utype = e->utype;
9820 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9821 enew->whereDefined = fileloc_copy (e->whereDefined);
9822 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9824 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9825 enew->used = e->used;
9827 enew->isPrivate = e->isPrivate;
9828 enew->hasNameError = e->hasNameError;
9829 enew->uses = filelocList_undefined;
9831 enew->storageclass = e->storageclass;
9832 enew->info = uinfo_copy (e->info, e->ukind);
9833 enew->warn = warnClause_copy (e->warn);
9835 DPRINTF (("Here we are..."));
9836 DPRINTF (("original: %s", uentry_unparseFull (e)));
9837 DPRINTF (("copy: %s", uentry_unparse (enew)));
9838 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9843 return uentry_undefined;
9848 uentry_setState (uentry res, uentry other)
9850 llassert (uentry_isValid (res));
9851 llassert (uentry_isValid (other));
9853 llassert (res->ukind == other->ukind);
9854 llassert (res->ukind == KVAR);
9856 res->sref = sRef_saveCopy (other->sref);
9857 res->used = other->used;
9858 filelocList_free (res->uses);
9859 res->uses = other->uses;
9860 other->uses = filelocList_undefined;
9861 res->lset = other->lset;
9865 uentry_mergeUses (uentry res, uentry other)
9867 llassert (uentry_isValid (res));
9868 llassert (uentry_isValid (other));
9870 res->used = other->used || res->used;
9871 res->lset = other->lset || res->lset;
9872 res->uses = filelocList_append (res->uses, other->uses);
9873 other->uses = filelocList_undefined;
9878 ** This is a really ugly routine.
9880 ** gack...fix this one day.
9885 ** >> res is the false branch, other is the true branch (or continuation)
9887 ** >> res is the true branch, other is the false branch (or continutation)
9894 ** References not effected by res are propagated from other.
9898 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9899 bool flip, clause cl, fileloc loc)
9903 message ("%s %q is %s %s, but %s %s.",
9904 ekind_capName (res->ukind), uentry_getName (res),
9905 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9906 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9909 if (sRef_isDead (res->sref))
9911 sRef_showStateInfo (res->sref);
9913 else if (sRef_isKept (res->sref))
9915 sRef_showAliasInfo (res->sref);
9917 else /* dependent */
9919 sRef_showAliasInfo (res->sref);
9920 sRef_showAliasInfo (other->sref);
9923 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9927 static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
9929 alkind rk = sRef_getAliasKind (rs);
9930 alkind ok = sRef_getAliasKind (os);
9932 if (alkind_isError (rk) || alkind_isError (ok))
9938 return ((sRef_isDead (rs)
9939 || (alkind_isKept (rk) && !alkind_isKept (ok))
9940 || (alkind_isDependent (rk)
9941 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
9942 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
9947 branchStateAltError (/*@notnull@*/ uentry res,
9948 /*@notnull@*/ uentry other, bool flip,
9949 clause cl, fileloc loc)
9953 message ("%s %q is %s %s, but %s %s.",
9954 ekind_capName (res->ukind), uentry_getName (res),
9955 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
9956 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
9959 if (sRef_isDead (other->sref))
9961 sRef_showStateInfo (other->sref);
9965 sRef_showAliasInfo (other->sref);
9968 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9969 sRef_setDefinedComplete (res->sref, fileloc_undefined);
9971 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
9972 sRef_setDefinedComplete (other->sref, fileloc_undefined);
9977 ** A reference is relevant for certain checks, only if it
9978 ** is not definitely null on this path (but not declared
9979 ** to always be null.)
9982 static bool uentry_relevantReference (sRef sr, bool flip)
9984 if (sRef_isKept (sr) || sRef_isDependent (sr))
9992 return !sRef_definitelyNullContext (sr);
9996 return !sRef_definitelyNullAltContext (sr);
10002 uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
10003 bool mustReturn, bool flip, bool opt,
10006 sRef rs = res->sref;
10007 sRef os = other->sref;
10009 DPRINTF (("Merge alias states: %s / %s",
10010 uentry_unparseFull (res),
10011 uentry_unparseFull (other)));
10013 if (sRef_isValid (rs))
10017 if (uentry_incompatibleMemoryStates (rs, os))
10019 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10020 sRef_unparseFull (rs), sRef_unparseFull (os)));
10022 if (sRef_isThroughArrayFetch (rs)
10023 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10025 if (sRef_isKept (rs) || sRef_isKept (os))
10027 sRef_maybeKill (rs, loc);
10029 else if (sRef_isPossiblyDead (os))
10031 sRef_maybeKill (rs, loc);
10040 if (uentry_relevantReference (os, flip))
10042 if (sRef_isLocalParamVar (rs)
10043 && (sRef_isLocalState (os)
10044 || sRef_isDependent (os)))
10046 if (sRef_isDependent (rs))
10048 sRef_setDependent (os, loc);
10052 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10057 branchStateError (res, other, flip, cl, loc);
10062 if (sRef_isKept (rs))
10064 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10065 sRef_setKept (os, loc);
10070 if (uentry_incompatibleMemoryStates (os, rs))
10072 if (uentry_relevantReference (rs, !flip))
10074 if (sRef_isLocalParamVar (rs)
10075 && (sRef_isDependent (rs)
10076 || sRef_isLocalState (rs)))
10078 if (sRef_isDependent (os))
10080 sRef_setDependent (rs, loc);
10084 sRef_setDefState (rs, SS_UNUSEABLE, loc);
10089 if (sRef_isParam (os))
10092 ** If the local variable associated
10093 ** with the param has the correct state,
10095 ** (e.g., free (s); s = new(); ...
10098 uentry uvar = usymtab_lookupSafe (other->uname);
10100 if (uentry_isValid (uvar)
10101 && ((sRef_isDead (os)
10102 && sRef_isOnly (uvar->sref))
10103 || (sRef_isDependent (os)
10104 && sRef_isOwned (uvar->sref))))
10110 branchStateAltError (res, other,
10116 DPRINTF (("Here: %s / %s",
10117 uentry_unparseFull (res),
10118 uentry_unparseFull (other)));
10120 branchStateAltError (res, other,
10127 if (sRef_isKept (os))
10129 sRef_setKept (rs, loc);
10135 DPRINTF (("Merge opt..."));
10136 sRef_mergeOptState (rs, os, cl, loc);
10137 DPRINTF (("Done!"));
10141 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10142 sRef_mergeState (rs, os, cl, loc);
10143 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10148 if (sRef_isModified (os))
10150 sRef_setModified (rs);
10155 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
10159 uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
10161 valueTable rvalues;
10162 valueTable ovalues;
10164 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10172 rvalues = sRef_getValueTable (res->sref);
10173 ovalues = sRef_getValueTable (other->sref);
10175 if (valueTable_isUndefined (ovalues))
10177 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10180 else if (valueTable_isUndefined (rvalues))
10183 ** Copy values from other
10187 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10188 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10193 valueTable_elements (ovalues, fkey, fval) {
10195 metaStateInfo minfo;
10196 stateCombinationTable sctable;
10200 tval = valueTable_lookup (rvalues, fkey);
10202 DPRINTF (("Merge value: %s / %s X %s", fkey,
10203 stateValue_unparse (fval), stateValue_unparse (tval)));
10205 minfo = context_lookupMetaStateInfo (fkey);
10206 llassert (stateValue_isDefined (tval));
10208 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10210 DPRINTF (("Cannot find meta state for: %s", fkey));
10215 llassert (metaStateInfo_isDefined (minfo));
10217 if (stateValue_isError (fval)
10218 || sRef_definitelyNullContext (res->sref))
10220 sRef_setMetaStateValueComplete (res->sref,
10221 fkey, stateValue_getValue (fval),
10222 stateValue_getLoc (fval));
10223 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10225 else if (stateValue_isError (tval)
10226 || sRef_definitelyNullAltContext (other->sref))
10228 DPRINTF (("Other branch is definitely null!"));
10230 else if (sRef_isStateUndefined (res->sref)
10231 || sRef_isDead (res->sref))
10233 ; /* Combination state doesn't matter if it is undefined or dead */
10237 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10238 metaStateInfo_unparse (minfo),
10239 stateValue_unparse (fval),
10240 stateValue_unparse (tval)));
10242 DPRINTF (("state values: %d / %d",
10243 stateValue_getValue (fval), stateValue_getValue (tval)));
10245 sctable = metaStateInfo_getMergeTable (minfo);
10247 DPRINTF (("Merge table: %s",
10248 stateCombinationTable_unparse (sctable)));
10250 msg = cstring_undefined;
10252 nval = stateCombinationTable_lookup (sctable,
10253 stateValue_getValue (fval),
10254 stateValue_getValue (tval),
10257 DPRINTF (("nval: %d / %d / %d", nval,
10258 stateValue_getValue (fval), stateValue_getValue (tval)));
10260 if (nval == stateValue_error)
10262 /*@i32 print extra info for assignments@*/
10264 if (uentry_isGlobalMarker (res))
10269 ("Control branches merge with incompatible global states (%s and %s)%q",
10270 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10271 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10272 cstring_isDefined (msg)
10273 ? message (": %s", msg) : cstring_undefined),
10276 sRef_showMetaStateInfo (res->sref, fkey);
10277 sRef_showMetaStateInfo (other->sref, fkey);
10285 ("Control branches merge with incompatible states for %q (%s and %s)%q",
10286 uentry_getName (res),
10287 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10288 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
10289 cstring_isDefined (msg)
10290 ? message (": %s", msg) : cstring_undefined),
10293 sRef_showMetaStateInfo (res->sref, fkey);
10294 sRef_showMetaStateInfo (other->sref, fkey);
10295 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10296 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10297 DPRINTF (("Null: %s / %s",
10298 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10299 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10305 if (nval == stateValue_getValue (fval)
10306 && nval != stateValue_getValue (tval))
10308 loc = stateValue_getLoc (fval);
10310 else if (nval == stateValue_getValue (tval)
10311 && nval != stateValue_getValue (fval))
10313 loc = stateValue_getLoc (tval);
10320 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10321 && nval == stateValue_getValue (fval)
10322 && nval == stateValue_getValue (tval))
10328 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10332 } end_valueTable_elements ;
10338 uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10339 bool flip, clause cl)
10341 if (cl == DOWHILECLAUSE)
10343 res->used = other->used || res->used;
10344 res->lset = other->lset || res->lset;
10345 res->uses = filelocList_append (res->uses, other->uses);
10346 other->uses = filelocList_undefined;
10350 if (sRef_isMacroParamRef (res->sref)
10351 && !uentry_isSefParam (other)
10352 && !uentry_isSefParam (res))
10354 bool hasError = FALSE;
10356 if (bool_equal (res->used, other->used))
10358 res->used = other->used;
10362 if (other->used && !flip)
10367 message ("Macro parameter %q used in true clause, "
10368 "but not in false clause",
10369 uentry_getName (res)),
10370 uentry_whereDeclared (res));
10377 message ("Macro parameter %q used in false clause, "
10378 "but not in true clause",
10379 uentry_getName (res)),
10380 uentry_whereDeclared (res));
10386 /* make it sef now, prevent more errors */
10387 res->info->var->kind = VKREFSEFPARAM;
10393 res->used = other->used || res->used;
10394 res->lset = other->lset || res->lset;
10395 res->uses = filelocList_append (res->uses, other->uses);
10396 other->uses = filelocList_undefined;
10402 uentry_mergeState (uentry res, uentry other, fileloc loc,
10403 bool mustReturn, bool flip, bool opt,
10406 llassert (uentry_isValid (res));
10407 llassert (uentry_isValid (other));
10409 llassert (res->ukind == other->ukind);
10410 llassert (res->ukind == KVAR);
10412 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10413 uentry_unparseFull (other)));
10415 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
10416 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
10417 uentry_mergeSetStates (res, other, loc, flip, cl);
10420 void uentry_setUsed (uentry e, fileloc loc)
10422 static bool firstTime = TRUE;
10423 static bool showUses = FALSE;
10424 static bool exportLocal = FALSE;
10426 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10430 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10432 showUses = context_getFlag (FLG_SHOWUSES);
10433 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10438 if (uentry_isValid (e))
10442 if (warnClause_isDefined (e->warn))
10444 flagSpec flg = warnClause_getFlag (e->warn);
10447 if (warnClause_hasMessage (e->warn))
10449 msg = cstring_copy (warnClause_getMessage (e->warn));
10453 msg = message ("Use of possibly dangerous %s",
10454 uentry_ekindNameLC (e));
10458 message ("%q: %q", msg, uentry_getName (e)),
10462 if (sRef_isMacroParamRef (e->sref))
10464 if (uentry_isYield (e) || uentry_isSefParam (e))
10470 if (context_inConditional ())
10474 message ("Macro parameter %q used in conditionally "
10475 "executed code (may or may not be "
10476 "evaluated exactly once)",
10477 uentry_getName (e)),
10480 e->info->var->kind = VKREFSEFPARAM;
10489 message ("Macro parameter %q used more than once",
10490 uentry_getName (e)),
10491 uentry_whereDeclared (e)))
10493 e->info->var->kind = VKREFSEFPARAM;
10500 if ((dp = uentry_directParamNo (e)) >= 0)
10502 uentry_setUsed (usymtab_getParam (dp), loc);
10507 if (!sRef_isLocalVar (e->sref))
10511 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10517 if (context_inMacro ())
10519 e->uses = filelocList_addUndefined (e->uses);
10523 e->uses = filelocList_addDifferentFile
10525 uentry_whereDeclared (e),
10534 bool uentry_isReturned (uentry u)
10536 return (uentry_isValid (u) && uentry_isVar (u)
10537 && (u->info->var->kind == VKRETPARAM
10538 || u->info->var->kind == VKSEFRETPARAM));
10541 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10543 llassert (uentry_isRealFunction (u));
10545 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
10547 stateClauseList clauses = uentry_getStateClauseList (u);
10548 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10550 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
10551 sRef_setAllocated (res, g_currentloc);
10553 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10554 stateClauseList_unparse (clauses)));
10557 ** This should be in exprNode_reflectEnsuresClause
10560 stateClauseList_postElements (clauses, cl)
10562 if (!stateClause_isGlobal (cl))
10564 sRefSet refs = stateClause_getRefs (cl);
10565 sRefMod modf = stateClause_getEffectFunction (cl);
10567 sRefSet_elements (refs, el)
10569 sRef base = sRef_getRootBase (el);
10571 if (sRef_isResult (base))
10575 sRef sr = sRef_fixBase (el, res);
10576 modf (sr, g_currentloc);
10583 } end_sRefSet_elements ;
10585 } end_stateClauseList_postElements ;
10593 sRefSet prefs = sRefSet_new ();
10594 sRef res = sRef_undefined;
10597 params = uentry_getParams (u);
10599 uentryList_elements (params, current)
10601 if (uentry_isReturned (current))
10603 if (exprNodeList_size (args) >= paramno)
10605 exprNode ecur = exprNodeList_nth (args, paramno);
10606 sRef tref = exprNode_getSref (ecur);
10608 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10610 if (sRef_isValid (tref))
10612 sRef tcref = sRef_copy (tref);
10614 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10616 if (sRef_isDead (tcref))
10618 sRef_setDefined (tcref, g_currentloc);
10619 sRef_setOnly (tcref, g_currentloc);
10622 if (sRef_isRefCounted (tcref))
10624 /* could be a new ref now (but only if its returned) */
10625 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10628 sRef_makeSafe (tcref);
10629 prefs = sRefSet_insert (prefs, tcref);
10635 } end_uentryList_elements ;
10637 if (sRefSet_size (prefs) > 0)
10639 nstate n = sRef_getNullState (u->sref);
10641 if (sRefSet_size (prefs) == 1)
10643 res = sRefSet_choose (prefs);
10647 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
10648 res = sRefSet_mergeIntoOne (prefs);
10651 if (nstate_isKnown (n))
10653 sRef_setNullState (res, n, g_currentloc);
10658 if (ctype_isFunction (u->utype))
10660 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10661 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
10665 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10668 if (sRef_isRefCounted (res))
10670 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10675 if (sRef_getNullState (res) == NS_ABSNULL)
10677 ctype ct = ctype_realType (u->utype);
10679 if (ctype_isAbstract (ct))
10681 sRef_setNotNull (res, g_currentloc);
10685 if (ctype_isUser (ct))
10687 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10691 sRef_setNotNull (res, g_currentloc);
10696 if (sRef_isRefCounted (res))
10698 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10700 else if (sRef_isKillRef (res))
10702 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10709 ak = sRef_getAliasKind (res);
10711 if (alkind_isImplicit (ak))
10713 sRef_setAliasKind (res,
10714 alkind_fixImplicit (ak),
10718 sRefSet_free (prefs);
10720 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
10725 static bool uentry_isRefCounted (uentry ue)
10727 ctype ct = uentry_getType (ue);
10729 if (ctype_isFunction (ct))
10731 return (ctype_isRefCounted (ctype_getReturnType (ct)));
10735 return (ctype_isRefCounted (ct));
10740 ** old was declared yield in the specification.
10741 ** new is declared in the iter implementation.
10744 void uentry_checkYieldParam (uentry old, uentry unew)
10748 llassert (uentry_isVariable (old));
10749 llassert (uentry_isVariable (unew));
10751 unew->info->var->kind = VKYIELDPARAM;
10752 (void) checkTypeConformance (old, unew, TRUE);
10753 checkVarConformance (old, unew, TRUE, FALSE);
10755 /* get rid of param marker */
10757 name = uentry_getName (unew);
10758 cstring_free (unew->uname);
10759 unew->uname = name;
10760 unew->info->var->kind = VKREFYIELDPARAM;
10762 uentry_setUsed (old, fileloc_undefined);
10763 uentry_setUsed (unew, fileloc_undefined);
10766 /*@observer@*/ cstring
10767 uentry_ekindName (uentry ue)
10769 if (uentry_isValid (ue))
10774 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10776 return cstring_makeLiteralTemp ("Datatype");
10778 return cstring_makeLiteralTemp ("Enum member");
10780 return cstring_makeLiteralTemp ("Constant");
10782 if (uentry_isParam (ue))
10784 return cstring_makeLiteralTemp ("Parameter");
10786 else if (uentry_isExpandedMacro (ue))
10788 return cstring_makeLiteralTemp ("Expanded macro");
10792 return cstring_makeLiteralTemp ("Variable");
10795 return cstring_makeLiteralTemp ("Function");
10797 return cstring_makeLiteralTemp ("Iterator");
10799 return cstring_makeLiteralTemp ("Iterator finalizer");
10801 return cstring_makeLiteralTemp ("Struct tag");
10803 return cstring_makeLiteralTemp ("Union tag");
10805 return cstring_makeLiteralTemp ("Enum tag");
10807 return cstring_makeLiteralTemp ("Optional parameters");
10812 return cstring_makeLiteralTemp ("<Undefined>");
10818 /*@observer@*/ cstring
10819 uentry_ekindNameLC (uentry ue)
10821 if (uentry_isValid (ue))
10826 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10828 return cstring_makeLiteralTemp ("datatype");
10830 return cstring_makeLiteralTemp ("enum member");
10832 return cstring_makeLiteralTemp ("constant");
10834 if (uentry_isParam (ue))
10836 return cstring_makeLiteralTemp ("parameter");
10838 else if (uentry_isExpandedMacro (ue))
10840 return cstring_makeLiteralTemp ("expanded macro");
10844 return cstring_makeLiteralTemp ("variable");
10847 return cstring_makeLiteralTemp ("function");
10849 return cstring_makeLiteralTemp ("iterator");
10851 return cstring_makeLiteralTemp ("iterator finalizer");
10853 return cstring_makeLiteralTemp ("struct tag");
10855 return cstring_makeLiteralTemp ("union tag");
10857 return cstring_makeLiteralTemp ("enum tag");
10859 return cstring_makeLiteralTemp ("optional parameters");
10864 return cstring_makeLiteralTemp ("<Undefined>");
10870 void uentry_setHasNameError (uentry ue)
10872 llassert (uentry_isValid (ue));
10874 ue->hasNameError = TRUE;
10877 void uentry_checkName (uentry ue)
10879 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10880 uentry_observeRealName (ue),
10881 bool_unparse (uentry_isVisibleExternally (ue))));
10883 if (uentry_isValid (ue)
10884 && !context_inXHFile ()
10885 && uentry_hasName (ue)
10886 && !uentry_isElipsisMarker (ue)
10887 && context_getFlag (FLG_NAMECHECKS)
10888 && !ue->hasNameError
10889 && !uentry_isEndIter (ue)
10890 && !fileloc_isBuiltin (uentry_whereLast (ue))
10891 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
10893 DPRINTF (("Here..."));
10895 if (uentry_isPriv (ue))
10897 ; /* any checks here? */
10899 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10901 ; /* no errors for externals */
10907 if (uentry_isExpandedMacro (ue))
10913 if (uentry_isExpandedMacro (ue))
10917 else if (uentry_isVariable (ue))
10919 sRef sr = uentry_getSref (ue);
10921 if (sRef_isValid (sr))
10923 scope = sRef_getScope (sr);
10930 else if (uentry_isFunction (ue)
10931 || uentry_isIter (ue)
10932 || uentry_isEndIter (ue)
10933 || uentry_isConstant (ue))
10935 scope = uentry_isStatic (ue) ? fileScope : globScope;
10937 else /* datatypes, etc. must be global */
10942 usymtab_checkDistinctName (ue, scope);
10945 if (context_getFlag (FLG_CPPNAMES))
10950 if (scope == globScope)
10952 checkExternalName (ue);
10954 else if (scope == fileScope)
10956 checkFileScopeName (ue);
10960 checkLocalName (ue);
10964 checkAnsiName (ue);
10969 /*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
10975 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
10978 if (!context_inMacro ())
10980 sRef_setGlobalScopeSafe ();
10983 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
10984 uentry_setUsed (ue, loc);
10986 tloc = fileloc_createExternal ();
10987 uentry_setDefined (ue, tloc);
10988 fileloc_free (tloc);
10989 uentry_setHasNameError (ue);
10991 if (context_getFlag (FLG_REPEATUNRECOG))
10993 uentry_markOwned (ue);
10997 ue = usymtab_supReturnFileEntry (ue);
11000 if (!context_inMacro ())
11002 sRef_clearGlobalScopeSafe ();
11008 uentry uentry_makeGlobalMarker ()
11013 llassert (sRef_inGlobalScope ());
11015 ue = uentry_makeVariableAux
11016 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11017 sRef_makeGlobalMarker (),
11020 tloc = fileloc_createExternal ();
11021 uentry_setUsed (ue, tloc);
11022 uentry_setDefined (ue, tloc);
11023 fileloc_free (tloc);
11024 uentry_setHasNameError (ue);
11030 bool uentry_isGlobalMarker (uentry ue)
11032 return (uentry_isValid (ue)
11033 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11036 /* new start modifications */
11038 /* start modifications */
11040 requires: p_e is defined, is a ptr/array variable
11042 effects: sets the state of the variable
11046 void uentry_setPossiblyNullTerminatedState (uentry p_e) {
11047 /*@access sRef@*/ /*i523 shouldn't do this! */
11048 if( uentry_isValid(p_e) ) {
11049 if( p_e->info != NULL) {
11050 if( p_e->info->var != NULL) {
11051 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11052 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11057 /*@noaccess sRef@*/
11059 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11063 requires: p_e is defined, is a ptr/array variable
11065 effects: sets the size of the buffer
11068 void uentry_setNullTerminatedState (uentry p_e) {
11069 if( uentry_isValid(p_e) ) {
11070 if( p_e->info != NULL) {
11071 if( p_e->info->var != NULL) {
11072 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
11073 /*@access sRef@*/ /*@i523 bad!*/
11074 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
11075 /*@noaccess sRef@*/
11081 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11085 requires: p_e is defined, is a ptr/array variable
11087 effects: sets the size of the buffer
11090 void uentry_setSize (uentry p_e, int size) {
11091 if( uentry_isValid(p_e) ) {
11092 if( p_e->info != NULL) {
11093 if( p_e->info->var != NULL) {
11094 p_e->info->var->bufinfo->size = size;
11095 /*@access sRef@*/ /*@i523 bad!*/
11096 p_e->sref->bufinfo.size = size;
11097 /*@noaccess sRef@*/
11103 fprintf(stderr, "uentry:Error in setSize\n");
11108 requires: p_e is defined, is a ptr/array variable
11110 effects: sets the length of the buffer
11113 void uentry_setLen (uentry p_e, int len) {
11114 if( uentry_isValid(p_e) ) {
11115 if( p_e->info != NULL) {
11116 if( p_e->info->var != NULL) {
11117 p_e->info->var->bufinfo->len = len;
11118 /*@access sRef@*/ /*@i523 bad!*/
11119 p_e->sref->bufinfo.len = len;
11120 /*@noaccess sRef@*/
11126 fprintf(stderr, "uentry:Error in setLen\n");
11131 bool uentry_hasMetaStateEnsures (uentry e)
11133 if (uentry_isValid (e) && uentry_isFunction (e))
11135 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11143 metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
11145 llassert (uentry_isValid (e) && uentry_isFunction (e));
11146 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);