1 #include <assert.h> /*drl take this out*/
3 ** LCLint - annotation-assisted static program checker
4 ** Copyright (C) 1994-2000 University of Virginia,
5 ** Massachusetts Institute of Technology
7 ** This program is free software; you can redistribute it and/or modify it
8 ** under the terms of the GNU General Public License as published by the
9 ** Free Software Foundation; either version 2 of the License, or (at your
10 ** option) any later version.
12 ** This program is distributed in the hope that it will be useful, but
13 ** WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** General Public License for more details.
17 ** The GNU General Public License is available from http://www.gnu.org/ or
18 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 ** MA 02111-1307, USA.
21 ** For information on lclint: lclint-request@cs.virginia.edu
22 ** To report a bug: lclint-bug@cs.virginia.edu
23 ** For more information: http://lclint.cs.virginia.edu
28 ** error reporting procedures
31 # include "lclintMacros.nf"
38 static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
39 /*@modifies *p_stream@*/ ;
42 static int lclerrors = 0;
45 static int lastfileloclen = 10;
46 static /*@only@*/ cstring lastmsg = cstring_undefined;
47 static int mcount = 0;
48 static /*@only@*/ cstring saveOneMessage = cstring_undefined;
49 static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
50 static /*@only@*/ fileloc lastbug = fileloc_undefined;
51 static bool llgenerrorreal (/*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
52 /*@modifies g_msgstream@*/ ;
53 static bool llgenerroraux (/*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
54 /*@modifies g_msgstream@*/ ;
55 static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
56 /*@globals lastfileloclen @*/
57 /*@modifies *p_stream@*/ ;
58 static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
59 /*@modifies *p_stream@*/ ;
61 static /*@null@*/ char *
62 maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
71 fprintf (stderr, " *** Please report bug to %s ***\n",
74 /* don't exit (EXIT_FAILURE); */
77 static bool s_needsPrepare = TRUE;
79 void prepareMessage (void)
81 if (context_isPreprocessing ()
83 && context_getDebug (FLG_SHOWSCAN))
86 fprintf (stderr, " >\n");
87 s_needsPrepare = FALSE;
93 void closeMessage (void)
95 if (context_isPreprocessing ()
96 && context_getDebug (FLG_SHOWSCAN))
99 fprintf (stderr, "< more preprocessing .");
101 llassert (!s_needsPrepare);
102 s_needsPrepare = TRUE;
111 llmsg (/*@only@*/ cstring s)
113 context_setNeednl ();
115 printMessage (g_msgstream, s);
120 lldiagmsg (/*@only@*/ cstring s)
122 context_setNeednl ();
124 printMessage (stderr, s);
129 llmsgplain (/*@only@*/ cstring s)
131 context_setNeednl ();
133 printMessage (g_msgstream, s);
137 void flagWarning (cstring s)
139 if (context_getFlag (FLG_WARNFLAGS))
143 if (fileloc_isBuiltin (g_currentloc))
145 llmsg (message ("Warning: %s", s));
149 llgenmsg (message ("Warning: %s", s), g_currentloc);
155 llgenhint (/*@only@*/ cstring s) /*@modifies g_msgstream@*/
157 context_setNeednl ();
158 printIndentMessage (g_msgstream, s, 2);
164 if (context_getFlag (FLG_HINTS) &&
165 !(context_inSuppressRegion () || context_inSuppressZone (g_currentloc)))
176 llshowhint (flagcode f)
178 if (context_getFlag (FLG_HINTS))
180 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
182 cstring desc = flagcodeHint (f);
184 if (cstring_isDefined (desc))
186 llgenhint (cstring_copy (desc));
194 llsuppresshint (char c, flagcode f)
197 if (context_getFlag (FLG_HINTS))
199 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
201 cstring desc = flagcodeHint (f);
202 context_setNeednl ();
205 if (flagcode_isNamePrefixFlag (f))
210 if (cstring_isDefined (desc))
212 llgenhint (message ("%s (%h%s will suppress message)", desc, c,
217 llgenhint (message ("(%h%s will suppress message)", c,
225 llnosuppresshint (flagcode f)
228 if (context_getFlag (FLG_FORCEHINTS))
230 cstring desc = flagcodeHint (f);
231 context_setNeednl ();
234 if (cstring_isDefined (desc))
236 printError (g_msgstream, message (" %s", desc));
241 /*@constant int MAXSEARCH; @*/
242 # define MAXSEARCH 20
244 /*@constant int MINLINE; @*/
247 typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
250 mstring_split (/*@returned@*/ char **sp,
251 /*@out@*/ nd_charp *tp,
252 int maxline, /*@in@*/ int *indentchars)
260 if (maxline < MINLINELEN)
262 maxline = MINLINELEN;
265 if (*indentchars > 0)
267 s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
270 nl = strchr (s, '\n');
275 ** if there is a newline in first maxline characters, split there
276 ** if line len is <= maxline, return no split
277 ** if there is a ':' or ';' followed by ' ' in first maxline characters,
278 ** split there unless the ' ' is followed by a '}', then
280 ** of the ';' is inside quotation marks
281 ** if there is a space or tab in last maxsearch characters, split there
282 ** else, split at maxline
284 ** special code: slash [1-9] after a newline means indent the rest <n> chars
288 if ((nl != NULL) && ((nl - s) < maxline))
298 if (*t >= '\1' && *t <= '\7')
300 *indentchars += (int) (*t - '\1') + 1;
307 else if (size_toInt (strlen (s)) < maxline)
315 char *lcolon, *lsemi, *splitat;
323 lcolon = strrchr (s, ':');
324 lsemi = strrchr (s, ';');
327 splitat = maxcp (lcolon, lsemi);
329 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
330 && *(splitat + 1) == ' ' && *(splitat + 2) != '}')
332 *(splitat + 1) = '\0';
338 while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
344 if (*t != ' ' && *t != '\t')
346 t = mstring_copy (s + maxline);
347 *(s + maxline) = '\0';
355 mstring_markFree (t);
364 if (*t == '\0') return;
367 ** returns unqualified as only
377 void limitmessage (/*@only@*/ cstring s, fileloc loc)
379 if (mcount > context_getLimit () + 1)
385 cstring flstring = fileloc_unparse (loc);
387 lastfileloclen = cstring_length (flstring);
388 cstring_free (saveOneMessage);
389 saveOneMessage = message ("%q: %q", flstring, s);
393 static int parseerrorcount = 0;
395 void cleanupMessages ()
399 if (context_unlimitedMessages ())
405 int unprinted = mcount - context_getLimit ();
409 if (unprinted == 1 && cstring_isDefined (saveOneMessage))
412 printError (g_msgstream, saveOneMessage);
414 saveOneMessage = cstring_undefined;
418 if (cstring_isDefined (saveOneMessage))
420 /* cstring_free (saveOneMessage); */
421 saveOneMessage = cstring_undefined;
424 fprintf (g_msgstream, "%s: (%d more similar errors unprinted)\n",
425 cstring_toCharsSafe (fileloc_filename (g_currentloc)),
426 mcount - context_getLimit ());
435 llgenmsg (/*@only@*/ cstring s, fileloc fl)
437 cstring flstring = fileloc_unparse (fl);
438 lastfileloclen = cstring_length (flstring);
441 (void) printError (g_msgstream, message ("%q: %q", flstring, s));
446 llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
448 cstring flstring = fileloc_unparse (fl);
451 (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), 3);
456 llgenindentmsgnoloc (/*@only@*/ cstring s)
459 (void) printIndentMessage (g_msgstream, s, 3);
464 llgentypeerroraux (flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
465 /*@only@*/ cstring s, fileloc fl)
467 cstring hint = cstring_undefined;
468 flagcode code = ocode;
469 flagcode hcode = INVALID_FLAG;
473 DPRINTF (("Type error: %s / %s : %s / %s",
474 exprNode_unparse (e1), exprNode_unparse (e2),
475 ctype_unparse (t1), ctype_unparse (t2)));
477 DPRINTF (("Bool: %s / %s",
478 bool_unparse (ctype_isBool (t1)),
479 bool_unparse (ctype_isBool (t2))));
482 ** Set the flag using the underlying types that didn't match.
485 while (ctype_isPointer (ut1) && ctype_isPointer (ut2)) {
486 ut1 = ctype_baseArrayPtr (ut1);
487 ut2 = ctype_baseArrayPtr (ut2);
490 if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
491 || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
493 hcode = FLG_FLOATDOUBLE;
495 else if ((exprNode_isCharLit (e1) && ctype_isInt (ut2))
496 || (exprNode_isCharLit (e2) && ctype_isInt (ut1)))
498 hcode = FLG_CHARINTLITERAL;
500 else if ((exprNode_isNumLit (e1) && ctype_isReal (ut2))
501 || (exprNode_isNumLit (e2) && ctype_isReal (ut1)))
503 hcode = FLG_NUMLITERAL;
505 else if ((ctype_isManifestBool (ut1) && ctype_isInt (ut2))
506 || (ctype_isInt (ut1) && ctype_isManifestBool (ut2)))
507 /* evs 2000-07-24: was ctype_isDirectBool */
511 else if (((ctype_isChar (ut1) && !ctype_isInt (ut1)) && ctype_isInt (ut2))
512 || ((ctype_isInt (ut1) && (ctype_isChar (ut2) && !ctype_isInt (ut2)))))
516 else if ((ctype_isInt (ut1) && ctype_isInt (ut2))
517 || (ctype_isChar (ut1) && ctype_isChar (ut2))
518 || (ctype_isDouble (ut1) && ctype_isDouble (ut2)))
520 if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
522 hcode = FLG_IGNORESIGNS;
526 hcode = FLG_IGNOREQUALS;
529 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
531 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
533 hcode = FLG_MATCHANYINTEGRAL;
535 else if (ctype_match (ut2, ctype_ulint))
537 hcode = FLG_LONGUNSIGNEDINTEGRAL;
539 else if (ctype_match (ut2, ctype_lint))
541 hcode = FLG_LONGINTEGRAL;
543 else if (ctype_isInt (ut2))
545 hcode = FLG_MATCHANYINTEGRAL;
552 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
554 ctype tr = ctype_realType (ut1);
556 if (ctype_isArbitraryIntegral (tr))
558 hcode = FLG_MATCHANYINTEGRAL;
560 else if (ctype_match (ut1, ctype_ulint))
562 if (ctype_isUnsignedIntegral (tr))
564 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
566 else if (ctype_isSignedIntegral (tr))
572 hcode = FLG_LONGUNSIGNEDINTEGRAL;
575 else if (ctype_match (ut1, ctype_lint))
577 if (ctype_isSignedIntegral (tr))
579 hcode = FLG_LONGSIGNEDINTEGRAL;
581 else if (ctype_isSignedIntegral (tr))
587 hcode = FLG_LONGINTEGRAL;
590 else if (ctype_isInt (ut1))
592 hcode = FLG_MATCHANYINTEGRAL;
599 else if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
601 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
602 ctype ct = uentry_getType (ue1);
604 if (ctype_match (ct, ut2))
607 hint = message ("Underlying types match, but %s is an "
608 "abstract type that is not accessible here.",
612 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
614 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
615 ctype ct = uentry_getType (ue);
617 if (ctype_match (ct, ut1))
620 hint = message ("Underlying types match, but %s is an "
621 "abstract type that is not accessible here.",
625 else if ((ctype_isEnum (ut1) && ctype_isArbitraryIntegral (ut2))
626 || (ctype_isEnum (ut2) && ctype_isArbitraryIntegral (ut1)))
630 else if ((ctype_isEnum (ut1) && ctype_isArbitraryIntegral (ut2))
631 || (ctype_isEnum (ut2) && ctype_isArbitraryIntegral (ut1)))
635 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
636 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
638 code = FLG_CHARUNSIGNEDCHAR;
640 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
642 code = FLG_RELAXTYPES;
646 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
647 ctype_unparse (ut2)));
650 if (cstring_isDefined (hint))
652 if (!context_suppressFlagMsg (ocode, fl))
654 return llgenhinterror (code, s, hint, fl);
665 if (llgenerroraux (s, fl, TRUE, FALSE))
667 if (hcode != INVALID_FLAG && hcode != ocode)
675 llsuppresshint ('-', code);
678 flagcode_recordError (code);
687 llgentypeerror (ctype t1, exprNode e1, ctype t2, exprNode e2,
688 /*@only@*/ cstring s, fileloc fl)
690 return llgentypeerroraux (FLG_TYPE, t1, e1, t2, e2, s, fl);
694 llgenformattypeerror (ctype t1, exprNode e1, ctype t2, exprNode e2,
695 /*@only@*/ cstring s, fileloc fl)
697 return llgentypeerroraux (FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
701 llgenerror (flagcode o, /*@only@*/ cstring s, fileloc fl)
703 if (llgenerroraux (s, fl, TRUE, FALSE))
705 llnosuppresshint (o);
706 flagcode_recordError (o);
712 flagcode_recordSuppressed (o);
718 llgenhinterror (flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
721 if (!context_suppressFlagMsg (o, fl))
723 if (llgenerroraux (s, fl, TRUE, FALSE))
725 flagcode_recordError (o);
727 if (context_getFlag (FLG_HINTS))
748 flagcode_recordSuppressed (o);
753 llrealerror (/*@only@*/ cstring s, fileloc fl)
755 return (llgenerrorreal (s, fl, TRUE, FALSE));
759 llgenerroraux (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
762 if (context_inSuppressZone (fl))
772 return (llgenerrorreal (s, fl, iserror, indent));
776 llforceerror (flagcode code, /*@only@*/ cstring s, fileloc fl)
778 flagcode_recordError (code);
779 (void) llgenerrorreal (s, fl, TRUE, FALSE);
784 llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
788 /* duplicate message (rescanning a header file */
790 if (!messageLog_add (context_messageLog (), fl, s))
796 if (iserror) context_hasError ();
798 if (context_unlimitedMessages ())
805 ** suppress excessive messages:
810 char *sc = cstring_toCharsSafe (s);
811 char *tmpmsg = strchr (sc, ':');
819 char *savechar = tmpmsg;
825 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
828 if (mcount == (context_getLimit () + 1))
830 limitmessage (s, fl);
834 if (mcount > (context_getLimit ()))
844 cstring_free (lastmsg);
845 lastmsg = cstring_fromCharsNew (tmpmsg);
849 if (context_hasAliasAnnote ())
851 char *sc = cstring_toCharsSafe (s);
852 char *fcolon = strchr (sc, ':');
853 cstring a = context_getAliasAnnote ();
858 s = message ("%q (%q)", s, a);
865 afterColon = cstring_fromCharsNew (fcolon + 1);
867 s = message ("%q (%q):%q", s, a, afterColon);
871 if (context_hasMessageAnnote ())
873 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
878 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
879 s = message ("%q (%q)", s, context_getMessageAnnote ());
880 /*@=dependenttrans@*/
887 afterColon = cstring_fromCharsNew (fcolon + 1);
889 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
890 s = message ("%q (%q):%q", s,
891 context_getMessageAnnote (), afterColon);
892 /*@=dependenttrans@*/
896 context_setNeednl ();
899 if (context_showFunction ())
901 cstring fname = fileloc_unparseFilename (g_currentloc);
903 if (context_inIterDef ())
905 fprintf (g_msgstream, "%s: (in iter %s)\n",
906 cstring_toCharsSafe (fname),
907 cstring_toCharsSafe (context_inFunctionName ()));
909 else if (context_inIterEnd ())
911 fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
912 cstring_toCharsSafe (fname),
913 cstring_toCharsSafe (context_inFunctionName ()));
915 else if (context_inMacro ())
917 fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
918 cstring_toCharsSafe (context_inFunctionName ()));
922 fprintf (g_msgstream, "%s: (in function %s)\n",
923 cstring_toCharsSafe (fname),
924 cstring_toCharsSafe (context_inFunctionName ()));
927 cstring_free (fname);
928 context_setShownFunction ();
931 flstring = fileloc_unparse (fl);
933 lastfileloclen = cstring_length (flstring);
937 printError (g_msgstream, message (" %q: %q", flstring, s));
941 printError (g_msgstream, message ("%q: %q", flstring, s));
950 ** message contains no '\n'
951 ** message fits in one line: print it
952 ** message fits in two lines with 3-space indent after fileloc: print it
953 ** split line with 5-space indent from left margin: print it
958 void printMessage (FILE *stream, /*@only@*/ cstring s)
960 printIndentMessage (stream, s, 0);
964 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
966 int maxlen = context_getLineLen ();
967 char *s = cstring_toCharsSafe (sc);
975 mstring_split (&st, &t, maxlen, &indent);
976 fprintf (stream, "%s\n", st);
979 } while (s != NULL) ;
985 void printError (FILE *stream, /*@only@*/ cstring sc)
987 int maxlen = context_getLineLen ();
988 int nspaces = lastfileloclen + 5;
989 int nextlen = maxlen - nspaces;
990 int len = cstring_length (sc);
992 char *s = cstring_toCharsSafe (sc);
996 if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
998 mstring_split (&s, &t, maxlen, &indent);
1000 fprintf (stream, "%s\n", s);
1004 len = mstring_length (t);
1006 if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1007 && len > (nextlen - 1))
1009 fprintf (stream, " %s\n", t);
1013 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1016 for (i = 0; i < nspaces; i++)
1021 spaces[nspaces] = '\0';
1026 mstring_split (&st, &t, nextlen, &indent);
1027 fprintf (stream, "%s%s\n", spaces, st);
1036 if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1038 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1040 if (nspaces < 1) nspaces = 1;
1042 nextlen = maxlen - nspaces;
1044 mstring_split (&s, &t, maxlen, &indent);
1046 fprintf (stream, "%s\n", s);
1050 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1053 for (i = 0; i < nspaces; i++)
1058 spaces[nspaces] = '\0';
1064 mstring_split (&st, &t, nextlen, &indent);
1065 fprintf (stream, "%s%s\n", spaces, st);
1074 nextlen = maxlen - nspaces;
1076 mstring_split (&s, &t, maxlen, &indent);
1078 fprintf (stream, "%s\n", s);
1082 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1085 for (i = 0; i < nspaces; i++)
1090 spaces[nspaces] = '\0';
1095 mstring_split (&st, &t, nextlen, &indent);
1096 fprintf (stream, "%s%s\n", spaces, st);
1108 llfatalbug (/*@only@*/ cstring s)
1111 printError (stderr, message ("%q: *** Fatal bug: %q",
1112 fileloc_unparse (g_currentloc), s));
1120 lclfatalbug (char *msg)
1124 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1132 checkParseError (void)
1134 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1136 llfatalerror (message ("%q: Cannot recover from parse error.",
1137 fileloc_unparse (g_currentloc)));
1141 void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1144 static int numbugs = 0;
1145 static bool inbug = FALSE;
1149 cstring temps = fileloc_unparseRaw (file, line);
1151 fprintf (stderr, "%s: Recursive bug detected: %s\n",
1152 cstring_toCharsSafe (temps),
1153 cstring_toCharsSafe (s));
1154 cstring_free (temps);
1163 if (fileloc_isRealLib (g_currentloc))
1165 llfatalerror (message ("%q: Library file appears to be corrupted. Error: %q:%s",
1166 fileloc_unparse (g_currentloc),
1167 fileloc_unparseRaw (file, line), s));
1170 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1172 llfatalerror (message ("%q: Cannot recover from parse error.",
1173 fileloc_unparse (g_currentloc)));
1176 (void) fflush (g_msgstream);
1177 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1178 fileloc_unparse (g_currentloc),
1179 fileloc_unparseRaw (file, line),
1183 (void) fflush (stderr);
1184 perror ("Possible system error diagnostic: ");
1185 (void) fflush (stderr);
1191 if (numbugs > 5 && fileloc_withinLines (lastbug, g_currentloc, 2))
1193 llfatalerror (message ("%q: Cannot recover from last bug.",
1194 fileloc_unparse (g_currentloc)));
1197 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1198 fileloc_free (lastbug);
1199 lastbug = fileloc_copy (g_currentloc);
1202 (void) fflush (stderr);
1204 assert(FALSE); /*drl take this out*/
1209 lclbug (/*@only@*/ cstring s)
1212 printError (stderr, message ("*** Internal Bug: %q", s));
1215 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1221 llfatalerror (cstring s)
1224 printError (stderr, s);
1225 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1230 llfatalerrorLoc (/*@only@*/ cstring s)
1233 (void) fflush (g_msgstream);
1234 printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1235 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1244 llgloberror (/*@only@*/ cstring s)
1246 if (context_inSuppressRegion ())
1252 context_setNeednl ();
1254 context_hasError ();
1255 flagcode_recordError (FLG_SPECIAL);
1256 printError (g_msgstream, s);
1265 return (lclerrors > 0);
1269 lclHadNewError (void)
1271 static int lastcall = 0;
1273 if (lclerrors > lastcall)
1275 lastcall = lclerrors;
1285 lclNumberErrors (void)
1291 lclerror (ltoken t, /*@only@*/ cstring msg)
1295 if (ltoken_getCode (t) != NOTTOKEN)
1297 cstring loc = ltoken_unparseLoc (t);
1299 lastfileloclen = cstring_length (loc);
1301 printError (g_msgstream, message ("%q: %q", loc, msg));
1305 printError (g_msgstream, msg);
1310 lclplainerror (/*@only@*/ cstring msg)
1314 printError (g_msgstream, msg);
1318 lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1321 (void) fflush (g_msgstream);
1322 printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1327 lclplainfatalerror (/*@only@*/ cstring msg)
1329 (void) fflush (g_msgstream);
1330 printError (stderr, message ("*** Cannot continue: %q", msg));
1335 lclRedeclarationError (ltoken id)
1337 cstring s = ltoken_getRawString (id);
1340 if (usymtab_existsEither (s))
1342 uentry le = usymtab_lookupEither (s);
1344 lclerror (id, message ("Respecification of %s", s));
1345 llgenindentmsg (message ("Previous specification of %q",
1346 uentry_getName (le)),
1347 uentry_whereSpecified (le));
1351 lclerror (id, message ("Identifier redeclared: %s", s));
1356 void genppllerror (flagcode code, /*@only@*/ cstring s)
1358 if (context_inSuppressZone (g_currentloc))
1364 if (context_getFlag (code))
1366 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1368 fprintf (g_msgstream, " >\n");
1373 if (code != FLG_PREPROC)
1375 llsuppresshint ('-', code);
1378 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1380 fprintf (stderr, "< more preprocessing .");
1390 void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1391 /*@only@*/ cstring hint)
1393 if (context_inSuppressZone (g_currentloc))
1396 cstring_free (hint);
1400 if (context_getFlag (code))
1403 context_clearPreprocessing ();
1406 context_setPreprocessing ();
1412 cstring_free (hint);
1417 void ppllerror (/*@only@*/ cstring s)
1419 genppllerror (FLG_PREPROC, s);
1422 void pplldiagmsg (cstring s)
1424 if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1426 fprintf (stderr, " >\n");
1428 fprintf (stderr, "< more preprocessing .");
1436 void loadllmsg (cstring s)
1438 if (context_getDebug (FLG_SHOWSCAN))
1440 fprintf (stderr, " >\n");
1442 fprintf (stderr, "< .");
1450 static void llreportparseerror (/*@only@*/ cstring s)
1452 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1458 llerror (FLG_SYNTAX, s);
1460 fileloc_free (lastparseerror);
1461 lastparseerror = fileloc_copy (g_currentloc);
1465 bool lloptgenerror (flagcode o, /*@only@*/ cstring s, fileloc loc)
1467 if (llrealerror (s, loc))
1469 llsuppresshint ('-', o);
1471 flagcode_recordError (o);
1475 flagcode_recordSuppressed (o);
1479 bool optgenerror2 (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1481 if (context_suppressFlagMsg (f1, loc))
1483 flagcode_recordSuppressed (f1);
1488 if (context_suppressFlagMsg (f2, loc))
1490 flagcode_recordSuppressed (f2);
1495 if (llrealerror (s, loc))
1497 llsuppresshint ('-', f2);
1498 flagcode_recordError (f2);
1503 flagcode_recordSuppressed (f2);
1509 bool optgenerror2n (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1512 if (context_suppressFlagMsg (f1, loc))
1514 flagcode_recordSuppressed (f1);
1519 if (context_suppressNotFlagMsg (f2, loc))
1521 flagcode_recordSuppressed (f2);
1526 if (llrealerror (s, loc))
1528 llsuppresshint ('+', f2);
1529 flagcode_recordError (f2);
1534 flagcode_recordSuppressed (f2);
1540 bool llnoptgenerror (flagcode o, /*@only@*/ cstring s, fileloc loc)
1542 if (llrealerror (s, loc))
1544 llsuppresshint ('+', o);
1545 flagcode_recordError (o);
1550 flagcode_recordSuppressed (o);
1554 void llparseerror (cstring s)
1556 if (context_getFlag (FLG_TRYTORECOVER))
1560 if (parseerrorcount > GIVEUPPARSE)
1562 if (cstring_isDefined (s))
1564 llfatalerror (message ("%q: Parse Error: %q. "
1565 "Too many errors, giving up.",
1566 fileloc_unparse (g_currentloc), s));
1570 llfatalerror (message ("%q: Parse Error. Too many errors, giving up.",
1571 fileloc_unparse (g_currentloc)));
1576 if (cstring_isDefined (s))
1578 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1583 llreportparseerror (message ("Parse Error. Attempting to continue."));
1591 if (cstring_isDefined (s))
1593 msg = message ("Parse Error: %q.", s);
1597 msg = message ("Parse Error.");
1601 (message ("%q: %s (For help on parse errors, "
1602 "see lclint -help parseerrors.)",
1603 fileloc_unparse (g_currentloc), msg));
1607 bool doCheck (bool x, cstring pred, cstring file, int line)
1610 llbug (message ("%q: Check Failed: %s",
1611 fileloc_unparseRaw (file, line),
1618 /*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1623 #ifndef HAVE_STRERROR
1626 result = strerror (errnum);
1629 /* VAXCRTL's strerror() takes an optional second argument, which only
1630 matters when the first argument is EVMSERR. However, it's simplest
1631 just to pass it unconditionally. `vaxc$errno' is declared in
1632 <errno.h>, and maintained by the library in parallel with `errno'.
1633 We assume that caller's `errnum' either matches the last setting of
1634 `errno' by the library or else does not have the value `EVMSERR'. */
1636 result = strerror (errnum, vaxc$errno);
1641 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1644 return cstring_fromChars (result);
1647 void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1652 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1653 fileloc_unparse (g_currentloc),
1654 fileloc_unparseRaw (file, line),
1666 (void) fflush (g_msgstream);
1667 (void) fflush (stderr);