2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
27 ** error reporting procedures
30 # include "lclintMacros.nf"
37 static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
38 /*@modifies *p_stream@*/ ;
41 static int lclerrors = 0;
44 static int lastfileloclen = 10;
45 static /*@only@*/ cstring lastmsg = cstring_undefined;
46 static int mcount = 0;
47 static /*@only@*/ cstring saveOneMessage = cstring_undefined;
48 static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
49 static /*@only@*/ fileloc lastbug = fileloc_undefined;
50 static bool llgenerrorreal (/*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
51 /*@modifies g_msgstream@*/ ;
52 static bool llgenerroraux (/*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
53 /*@modifies g_msgstream@*/ ;
54 static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
55 /*@globals lastfileloclen @*/
56 /*@modifies *p_stream@*/ ;
57 static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
58 /*@modifies *p_stream@*/ ;
60 static /*@null@*/ char *
61 maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
70 fprintf (stderr, " *** Please report bug to %s ***\n",
73 /* don't exit (EXIT_FAILURE); */
76 static bool s_needsPrepare = TRUE;
78 void prepareMessage (void)
80 if (context_isPreprocessing ()
82 && context_getDebug (FLG_SHOWSCAN))
85 fprintf (stderr, " >\n");
86 s_needsPrepare = FALSE;
92 void closeMessage (void)
94 if (context_isPreprocessing ()
95 && context_getDebug (FLG_SHOWSCAN))
98 fprintf (stderr, "< more preprocessing .");
100 llassert (!s_needsPrepare);
101 s_needsPrepare = TRUE;
110 llmsg (/*@only@*/ cstring s)
112 context_setNeednl ();
114 printMessage (g_msgstream, s);
119 lldiagmsg (/*@only@*/ cstring s)
121 context_setNeednl ();
123 printMessage (stderr, s);
128 llmsgplain (/*@only@*/ cstring s)
130 context_setNeednl ();
132 printMessage (g_msgstream, s);
136 void flagWarning (cstring s)
138 if (context_getFlag (FLG_WARNFLAGS))
142 if (fileloc_isBuiltin (g_currentloc))
144 llmsg (message ("Warning: %s", s));
148 llgenmsg (message ("Warning: %s", s), g_currentloc);
154 llgenhint (/*@only@*/ cstring s) /*@modifies g_msgstream@*/
156 context_setNeednl ();
157 printIndentMessage (g_msgstream, s, 2);
163 if (context_getFlag (FLG_HINTS) &&
164 !(context_inSuppressRegion () || context_inSuppressZone (g_currentloc)))
175 llshowhint (flagcode f)
177 if (context_getFlag (FLG_HINTS))
179 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
181 cstring desc = flagcodeHint (f);
183 if (cstring_isDefined (desc))
185 llgenhint (cstring_copy (desc));
193 llsuppresshint (char c, flagcode f)
196 if (context_getFlag (FLG_HINTS))
198 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
200 cstring desc = flagcodeHint (f);
201 context_setNeednl ();
204 if (flagcode_isNamePrefixFlag (f))
209 if (cstring_isDefined (desc))
211 llgenhint (message ("%s (%h%s will suppress message)", desc, c,
216 llgenhint (message ("(%h%s will suppress message)", c,
224 llnosuppresshint (flagcode f)
227 if (context_getFlag (FLG_FORCEHINTS))
229 cstring desc = flagcodeHint (f);
230 context_setNeednl ();
233 if (cstring_isDefined (desc))
235 printError (g_msgstream, message (" %s", desc));
240 /*@constant int MAXSEARCH; @*/
241 # define MAXSEARCH 20
243 /*@constant int MINLINE; @*/
246 typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
249 mstring_split (/*@returned@*/ char **sp,
250 /*@out@*/ nd_charp *tp,
251 int maxline, /*@in@*/ int *indentchars)
259 if (maxline < MINLINELEN)
261 maxline = MINLINELEN;
264 if (*indentchars > 0)
266 s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
269 nl = strchr (s, '\n');
274 ** if there is a newline in first maxline characters, split there
275 ** if line len is <= maxline, return no split
276 ** if there is a ':' or ';' followed by ' ' in first maxline characters,
277 ** split there unless the ' ' is followed by a '}', then
279 ** of the ';' is inside quotation marks
280 ** if there is a space or tab in last maxsearch characters, split there
281 ** else, split at maxline
283 ** special code: slash [1-9] after a newline means indent the rest <n> chars
287 if ((nl != NULL) && ((nl - s) < maxline))
297 if (*t >= '\1' && *t <= '\7')
299 *indentchars += (int) (*t - '\1') + 1;
306 else if (size_toInt (strlen (s)) < maxline)
314 char *lcolon, *lsemi, *splitat;
322 lcolon = strrchr (s, ':');
323 lsemi = strrchr (s, ';');
326 splitat = maxcp (lcolon, lsemi);
328 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
329 && *(splitat + 1) == ' ' && *(splitat + 2) != '}')
331 *(splitat + 1) = '\0';
337 while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
343 if (*t != ' ' && *t != '\t')
345 t = mstring_copy (s + maxline);
346 *(s + maxline) = '\0';
354 mstring_markFree (t);
363 if (*t == '\0') return;
366 ** returns unqualified as only
376 void limitmessage (/*@only@*/ cstring s, fileloc loc)
378 if (mcount > context_getLimit () + 1)
384 cstring flstring = fileloc_unparse (loc);
386 lastfileloclen = cstring_length (flstring);
387 cstring_free (saveOneMessage);
388 saveOneMessage = message ("%q: %q", flstring, s);
392 static int parseerrorcount = 0;
394 void cleanupMessages ()
398 if (context_unlimitedMessages ())
404 int unprinted = mcount - context_getLimit ();
408 if (unprinted == 1 && cstring_isDefined (saveOneMessage))
411 printError (g_msgstream, saveOneMessage);
413 saveOneMessage = cstring_undefined;
417 if (cstring_isDefined (saveOneMessage))
419 /* cstring_free (saveOneMessage); */
420 saveOneMessage = cstring_undefined;
423 fprintf (g_msgstream, "%s: (%d more similar errors unprinted)\n",
424 cstring_toCharsSafe (fileloc_filename (g_currentloc)),
425 mcount - context_getLimit ());
434 llgenmsg (/*@only@*/ cstring s, fileloc fl)
436 cstring flstring = fileloc_unparse (fl);
437 lastfileloclen = cstring_length (flstring);
440 (void) printError (g_msgstream, message ("%q: %q", flstring, s));
445 llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
447 cstring flstring = fileloc_unparse (fl);
450 (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), 3);
455 llgenindentmsgnoloc (/*@only@*/ cstring s)
458 (void) printIndentMessage (g_msgstream, s, 3);
463 llgentypeerroraux (flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
464 /*@only@*/ cstring s, fileloc fl)
466 cstring hint = cstring_undefined;
467 flagcode code = ocode;
468 flagcode hcode = INVALID_FLAG;
472 DPRINTF (("Type error: %s / %s : %s / %s",
473 exprNode_unparse (e1), exprNode_unparse (e2),
474 ctype_unparse (t1), ctype_unparse (t2)));
476 DPRINTF (("Bool: %s / %s",
477 bool_unparse (ctype_isBool (t1)),
478 bool_unparse (ctype_isBool (t2))));
481 ** Set the flag using the underlying types that didn't match.
484 while (ctype_isPointer (ut1) && ctype_isPointer (ut2)) {
485 ut1 = ctype_baseArrayPtr (ut1);
486 ut2 = ctype_baseArrayPtr (ut2);
489 if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
490 || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
492 hcode = FLG_FLOATDOUBLE;
494 else if ((exprNode_isCharLit (e1) && ctype_isInt (ut2))
495 || (exprNode_isCharLit (e2) && ctype_isInt (ut1)))
497 hcode = FLG_CHARINTLITERAL;
499 else if ((exprNode_isNumLit (e1) && ctype_isReal (ut2))
500 || (exprNode_isNumLit (e2) && ctype_isReal (ut1)))
502 hcode = FLG_NUMLITERAL;
504 else if ((ctype_isManifestBool (ut1) && ctype_isInt (ut2))
505 || (ctype_isInt (ut1) && ctype_isManifestBool (ut2)))
506 /* evs 2000-07-24: was ctype_isDirectBool */
510 else if (((ctype_isChar (ut1) && !ctype_isInt (ut1)) && ctype_isInt (ut2))
511 || ((ctype_isInt (ut1) && (ctype_isChar (ut2) && !ctype_isInt (ut2)))))
515 else if ((ctype_isInt (ut1) && ctype_isInt (ut2))
516 || (ctype_isChar (ut1) && ctype_isChar (ut2))
517 || (ctype_isDouble (ut1) && ctype_isDouble (ut2)))
519 if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
521 hcode = FLG_IGNORESIGNS;
525 hcode = FLG_IGNOREQUALS;
528 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
530 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
532 hcode = FLG_MATCHANYINTEGRAL;
534 else if (ctype_match (ut2, ctype_ulint))
536 hcode = FLG_LONGUNSIGNEDINTEGRAL;
538 else if (ctype_match (ut2, ctype_lint))
540 hcode = FLG_LONGINTEGRAL;
542 else if (ctype_isInt (ut2))
544 hcode = FLG_MATCHANYINTEGRAL;
551 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
553 ctype tr = ctype_realType (ut1);
555 if (ctype_isArbitraryIntegral (tr))
557 hcode = FLG_MATCHANYINTEGRAL;
559 else if (ctype_match (ut1, ctype_ulint))
561 if (ctype_isUnsignedIntegral (tr))
563 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
565 else if (ctype_isSignedIntegral (tr))
571 hcode = FLG_LONGUNSIGNEDINTEGRAL;
574 else if (ctype_match (ut1, ctype_lint))
576 if (ctype_isSignedIntegral (tr))
578 hcode = FLG_LONGSIGNEDINTEGRAL;
580 else if (ctype_isSignedIntegral (tr))
586 hcode = FLG_LONGINTEGRAL;
589 else if (ctype_isInt (ut1))
591 hcode = FLG_MATCHANYINTEGRAL;
598 else if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
600 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
601 ctype ct = uentry_getType (ue1);
603 if (ctype_match (ct, ut2))
606 hint = message ("Underlying types match, but %s is an "
607 "abstract type that is not accessible here.",
611 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
613 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
614 ctype ct = uentry_getType (ue);
616 if (ctype_match (ct, ut1))
619 hint = message ("Underlying types match, but %s is an "
620 "abstract type that is not accessible here.",
624 else if ((ctype_isEnum (ut1) && ctype_isArbitraryIntegral (ut2))
625 || (ctype_isEnum (ut2) && ctype_isArbitraryIntegral (ut1)))
629 else if ((ctype_isEnum (ut1) && ctype_isArbitraryIntegral (ut2))
630 || (ctype_isEnum (ut2) && ctype_isArbitraryIntegral (ut1)))
634 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
635 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
637 code = FLG_CHARUNSIGNEDCHAR;
639 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
641 code = FLG_RELAXTYPES;
645 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
646 ctype_unparse (ut2)));
649 if (cstring_isDefined (hint))
651 if (!context_suppressFlagMsg (ocode, fl))
653 return llgenhinterror (code, s, hint, fl);
664 if (llgenerroraux (s, fl, TRUE, FALSE))
666 if (hcode != INVALID_FLAG && hcode != ocode)
674 llsuppresshint ('-', code);
677 flagcode_recordError (code);
686 llgentypeerror (ctype t1, exprNode e1, ctype t2, exprNode e2,
687 /*@only@*/ cstring s, fileloc fl)
689 return llgentypeerroraux (FLG_TYPE, t1, e1, t2, e2, s, fl);
693 llgenformattypeerror (ctype t1, exprNode e1, ctype t2, exprNode e2,
694 /*@only@*/ cstring s, fileloc fl)
696 return llgentypeerroraux (FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
700 llgenerror (flagcode o, /*@only@*/ cstring s, fileloc fl)
702 if (llgenerroraux (s, fl, TRUE, FALSE))
704 llnosuppresshint (o);
705 flagcode_recordError (o);
711 flagcode_recordSuppressed (o);
717 llgenhinterror (flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
720 if (!context_suppressFlagMsg (o, fl))
722 if (llgenerroraux (s, fl, TRUE, FALSE))
724 flagcode_recordError (o);
726 if (context_getFlag (FLG_HINTS))
747 flagcode_recordSuppressed (o);
752 llrealerror (/*@only@*/ cstring s, fileloc fl)
754 return (llgenerrorreal (s, fl, TRUE, FALSE));
758 llgenerroraux (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
761 if (context_inSuppressZone (fl))
771 return (llgenerrorreal (s, fl, iserror, indent));
775 llforceerror (flagcode code, /*@only@*/ cstring s, fileloc fl)
777 flagcode_recordError (code);
778 (void) llgenerrorreal (s, fl, TRUE, FALSE);
783 llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
787 /* duplicate message (rescanning a header file */
789 if (!messageLog_add (context_messageLog (), fl, s))
795 if (iserror) context_hasError ();
797 if (context_unlimitedMessages ())
804 ** suppress excessive messages:
809 char *sc = cstring_toCharsSafe (s);
810 char *tmpmsg = strchr (sc, ':');
818 char *savechar = tmpmsg;
824 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
827 if (mcount == (context_getLimit () + 1))
829 limitmessage (s, fl);
833 if (mcount > (context_getLimit ()))
843 cstring_free (lastmsg);
844 lastmsg = cstring_fromCharsNew (tmpmsg);
848 if (context_hasAliasAnnote ())
850 char *sc = cstring_toCharsSafe (s);
851 char *fcolon = strchr (sc, ':');
852 cstring a = context_getAliasAnnote ();
857 s = message ("%q (%q)", s, a);
864 afterColon = cstring_fromCharsNew (fcolon + 1);
866 s = message ("%q (%q):%q", s, a, afterColon);
870 if (context_hasMessageAnnote ())
872 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
877 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
878 s = message ("%q (%q)", s, context_getMessageAnnote ());
879 /*@=dependenttrans@*/
886 afterColon = cstring_fromCharsNew (fcolon + 1);
888 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
889 s = message ("%q (%q):%q", s,
890 context_getMessageAnnote (), afterColon);
891 /*@=dependenttrans@*/
895 context_setNeednl ();
898 if (context_showFunction ())
900 cstring fname = fileloc_unparseFilename (g_currentloc);
902 if (context_inIterDef ())
904 fprintf (g_msgstream, "%s: (in iter %s)\n",
905 cstring_toCharsSafe (fname),
906 cstring_toCharsSafe (context_inFunctionName ()));
908 else if (context_inIterEnd ())
910 fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
911 cstring_toCharsSafe (fname),
912 cstring_toCharsSafe (context_inFunctionName ()));
914 else if (context_inMacro ())
916 fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
917 cstring_toCharsSafe (context_inFunctionName ()));
921 fprintf (g_msgstream, "%s: (in function %s)\n",
922 cstring_toCharsSafe (fname),
923 cstring_toCharsSafe (context_inFunctionName ()));
926 cstring_free (fname);
927 context_setShownFunction ();
930 flstring = fileloc_unparse (fl);
932 lastfileloclen = cstring_length (flstring);
936 printError (g_msgstream, message (" %q: %q", flstring, s));
940 printError (g_msgstream, message ("%q: %q", flstring, s));
949 ** message contains no '\n'
950 ** message fits in one line: print it
951 ** message fits in two lines with 3-space indent after fileloc: print it
952 ** split line with 5-space indent from left margin: print it
957 void printMessage (FILE *stream, /*@only@*/ cstring s)
959 printIndentMessage (stream, s, 0);
963 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
965 int maxlen = context_getLineLen ();
966 char *s = cstring_toCharsSafe (sc);
974 mstring_split (&st, &t, maxlen, &indent);
975 fprintf (stream, "%s\n", st);
978 } while (s != NULL) ;
984 void printError (FILE *stream, /*@only@*/ cstring sc)
986 int maxlen = context_getLineLen ();
987 int nspaces = lastfileloclen + 5;
988 int nextlen = maxlen - nspaces;
989 int len = cstring_length (sc);
991 char *s = cstring_toCharsSafe (sc);
995 if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
997 mstring_split (&s, &t, maxlen, &indent);
999 fprintf (stream, "%s\n", s);
1003 len = mstring_length (t);
1005 if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1006 && len > (nextlen - 1))
1008 fprintf (stream, " %s\n", t);
1012 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1015 for (i = 0; i < nspaces; i++)
1020 spaces[nspaces] = '\0';
1025 mstring_split (&st, &t, nextlen, &indent);
1026 fprintf (stream, "%s%s\n", spaces, st);
1035 if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1037 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1039 if (nspaces < 1) nspaces = 1;
1041 nextlen = maxlen - nspaces;
1043 mstring_split (&s, &t, maxlen, &indent);
1045 fprintf (stream, "%s\n", s);
1049 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1052 for (i = 0; i < nspaces; i++)
1057 spaces[nspaces] = '\0';
1063 mstring_split (&st, &t, nextlen, &indent);
1064 fprintf (stream, "%s%s\n", spaces, st);
1073 nextlen = maxlen - nspaces;
1075 mstring_split (&s, &t, maxlen, &indent);
1077 fprintf (stream, "%s\n", s);
1081 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1084 for (i = 0; i < nspaces; i++)
1089 spaces[nspaces] = '\0';
1094 mstring_split (&st, &t, nextlen, &indent);
1095 fprintf (stream, "%s%s\n", spaces, st);
1107 llfatalbug (/*@only@*/ cstring s)
1110 printError (stderr, message ("%q: *** Fatal bug: %q",
1111 fileloc_unparse (g_currentloc), s));
1119 lclfatalbug (char *msg)
1123 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1131 checkParseError (void)
1133 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1135 llfatalerror (message ("%q: Cannot recover from parse error.",
1136 fileloc_unparse (g_currentloc)));
1140 void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1143 static int numbugs = 0;
1144 static bool inbug = FALSE;
1148 cstring temps = fileloc_unparseRaw (file, line);
1150 fprintf (stderr, "%s: Recursive bug detected: %s\n",
1151 cstring_toCharsSafe (temps),
1152 cstring_toCharsSafe (s));
1153 cstring_free (temps);
1162 if (fileloc_isRealLib (g_currentloc))
1164 llfatalerror (message ("%q: Library file appears to be corrupted. Error: %q:%s",
1165 fileloc_unparse (g_currentloc),
1166 fileloc_unparseRaw (file, line), s));
1169 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1171 llfatalerror (message ("%q: Cannot recover from parse error.",
1172 fileloc_unparse (g_currentloc)));
1175 (void) fflush (g_msgstream);
1176 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1177 fileloc_unparse (g_currentloc),
1178 fileloc_unparseRaw (file, line),
1182 (void) fflush (stderr);
1183 perror ("Possible system error diagnostic: ");
1184 (void) fflush (stderr);
1190 if (numbugs > 5 && fileloc_withinLines (lastbug, g_currentloc, 2))
1192 llfatalerror (message ("%q: Cannot recover from last bug.",
1193 fileloc_unparse (g_currentloc)));
1196 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1197 fileloc_free (lastbug);
1198 lastbug = fileloc_copy (g_currentloc);
1201 (void) fflush (stderr);
1207 lclbug (/*@only@*/ cstring s)
1210 printError (stderr, message ("*** Internal Bug: %q", s));
1213 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1219 llfatalerror (cstring s)
1222 printError (stderr, s);
1223 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1228 llfatalerrorLoc (/*@only@*/ cstring s)
1231 (void) fflush (g_msgstream);
1232 printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1233 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1242 llgloberror (/*@only@*/ cstring s)
1244 if (context_inSuppressRegion ())
1250 context_setNeednl ();
1252 context_hasError ();
1253 flagcode_recordError (FLG_SPECIAL);
1254 printError (g_msgstream, s);
1263 return (lclerrors > 0);
1267 lclHadNewError (void)
1269 static int lastcall = 0;
1271 if (lclerrors > lastcall)
1273 lastcall = lclerrors;
1283 lclNumberErrors (void)
1289 lclerror (ltoken t, /*@only@*/ cstring msg)
1293 if (ltoken_getCode (t) != NOTTOKEN)
1295 cstring loc = ltoken_unparseLoc (t);
1297 lastfileloclen = cstring_length (loc);
1299 printError (g_msgstream, message ("%q: %q", loc, msg));
1303 printError (g_msgstream, msg);
1308 lclplainerror (/*@only@*/ cstring msg)
1312 printError (g_msgstream, msg);
1316 lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1319 (void) fflush (g_msgstream);
1320 printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1325 lclplainfatalerror (/*@only@*/ cstring msg)
1327 (void) fflush (g_msgstream);
1328 printError (stderr, message ("*** Cannot continue: %q", msg));
1333 lclRedeclarationError (ltoken id)
1335 cstring s = ltoken_getRawString (id);
1338 if (usymtab_existsEither (s))
1340 uentry le = usymtab_lookupEither (s);
1342 lclerror (id, message ("Respecification of %s", s));
1343 llgenindentmsg (message ("Previous specification of %q",
1344 uentry_getName (le)),
1345 uentry_whereSpecified (le));
1349 lclerror (id, message ("Identifier redeclared: %s", s));
1354 void genppllerror (flagcode code, /*@only@*/ cstring s)
1356 if (context_inSuppressZone (g_currentloc))
1362 if (context_getFlag (code))
1364 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1366 fprintf (g_msgstream, " >\n");
1371 if (code != FLG_PREPROC)
1373 llsuppresshint ('-', code);
1376 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1378 fprintf (stderr, "< more preprocessing .");
1388 void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1389 /*@only@*/ cstring hint)
1391 if (context_inSuppressZone (g_currentloc))
1394 cstring_free (hint);
1398 if (context_getFlag (code))
1401 context_clearPreprocessing ();
1404 context_setPreprocessing ();
1410 cstring_free (hint);
1415 void ppllerror (/*@only@*/ cstring s)
1417 genppllerror (FLG_PREPROC, s);
1420 void pplldiagmsg (cstring s)
1422 if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1424 fprintf (stderr, " >\n");
1426 fprintf (stderr, "< more preprocessing .");
1434 void loadllmsg (cstring s)
1436 if (context_getDebug (FLG_SHOWSCAN))
1438 fprintf (stderr, " >\n");
1440 fprintf (stderr, "< .");
1448 static void llreportparseerror (/*@only@*/ cstring s)
1450 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1456 llerror (FLG_SYNTAX, s);
1458 fileloc_free (lastparseerror);
1459 lastparseerror = fileloc_copy (g_currentloc);
1463 bool lloptgenerror (flagcode o, /*@only@*/ cstring s, fileloc loc)
1465 if (llrealerror (s, loc))
1467 llsuppresshint ('-', o);
1469 flagcode_recordError (o);
1473 flagcode_recordSuppressed (o);
1477 bool optgenerror2 (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1479 if (context_suppressFlagMsg (f1, loc))
1481 flagcode_recordSuppressed (f1);
1486 if (context_suppressFlagMsg (f2, loc))
1488 flagcode_recordSuppressed (f2);
1493 if (llrealerror (s, loc))
1495 llsuppresshint ('-', f2);
1496 flagcode_recordError (f2);
1501 flagcode_recordSuppressed (f2);
1507 bool optgenerror2n (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1510 if (context_suppressFlagMsg (f1, loc))
1512 flagcode_recordSuppressed (f1);
1517 if (context_suppressNotFlagMsg (f2, loc))
1519 flagcode_recordSuppressed (f2);
1524 if (llrealerror (s, loc))
1526 llsuppresshint ('+', f2);
1527 flagcode_recordError (f2);
1532 flagcode_recordSuppressed (f2);
1538 bool llnoptgenerror (flagcode o, /*@only@*/ cstring s, fileloc loc)
1540 if (llrealerror (s, loc))
1542 llsuppresshint ('+', o);
1543 flagcode_recordError (o);
1548 flagcode_recordSuppressed (o);
1552 void llparseerror (cstring s)
1554 if (context_getFlag (FLG_TRYTORECOVER))
1558 if (parseerrorcount > GIVEUPPARSE)
1560 if (cstring_isDefined (s))
1562 llfatalerror (message ("%q: Parse Error: %q. "
1563 "Too many errors, giving up.",
1564 fileloc_unparse (g_currentloc), s));
1568 llfatalerror (message ("%q: Parse Error. Too many errors, giving up.",
1569 fileloc_unparse (g_currentloc)));
1574 if (cstring_isDefined (s))
1576 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1581 llreportparseerror (message ("Parse Error. Attempting to continue."));
1589 if (cstring_isDefined (s))
1591 msg = message ("Parse Error: %q.", s);
1595 msg = message ("Parse Error.");
1599 (message ("%q: %s (For help on parse errors, "
1600 "see lclint -help parseerrors.)",
1601 fileloc_unparse (g_currentloc), msg));
1605 bool doCheck (bool x, cstring pred, cstring file, int line)
1608 llbug (message ("%q: Check Failed: %s",
1609 fileloc_unparseRaw (file, line),
1616 /*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1621 #ifndef HAVE_STRERROR
1624 result = strerror (errnum);
1627 /* VAXCRTL's strerror() takes an optional second argument, which only
1628 matters when the first argument is EVMSERR. However, it's simplest
1629 just to pass it unconditionally. `vaxc$errno' is declared in
1630 <errno.h>, and maintained by the library in parallel with `errno'.
1631 We assume that caller's `errnum' either matches the last setting of
1632 `errno' by the library or else does not have the value `EVMSERR'. */
1634 result = strerror (errnum, vaxc$errno);
1639 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1642 return cstring_fromChars (result);
1645 void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1650 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1651 fileloc_unparse (g_currentloc),
1652 fileloc_unparseRaw (file, line),
1664 (void) fflush (g_msgstream);
1665 (void) fflush (stderr);