]> andersk Git - splint.git/blame - src/llerror.c
Fixed all /*@i...@*/ tags (except 1).
[splint.git] / src / llerror.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
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.
10**
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.
15**
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.
19**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
11db3170 22** For more information: http://www.splint.org
616915dd 23*/
24/*
25** llerror.c
26**
27** error reporting procedures
28*/
29
1b8ae690 30# include "splintMacros.nf"
616915dd 31# include <string.h>
32# include <errno.h>
b73d1009 33# include "basic.h"
616915dd 34# include "llmain.h"
b072092f 35# include "cpperror.h"
4dd72714 36# include "Headers/version.h" /* Visual C++ finds a different version.h on some path! */
616915dd 37
28bf4b0b 38/* Don't allow possibly-recursive assertion failures. */
39# undef llassert
40# define llassert llassertprotect
41
616915dd 42static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
43 /*@modifies *p_stream@*/ ;
44
616915dd 45static int lclerrors = 0;
abd7f895 46static size_t lastfileloclen = 10;
616915dd 47static /*@only@*/ cstring lastmsg = cstring_undefined;
48static int mcount = 0;
49static /*@only@*/ cstring saveOneMessage = cstring_undefined;
50static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
51static /*@only@*/ fileloc lastbug = fileloc_undefined;
53306cab 52static bool llgenerrorreal (flagcode p_code,
53 char *p_srcFile, int p_srcLine,
54 /*@only@*/ cstring p_s,
55 /*@temp@*/ cstring p_addtext,
56 fileloc p_fl, bool p_iserror, bool p_indent)
80489f0a 57 /*@modifies g_warningstream@*/ ;
53306cab 58static bool llgenerroraux (flagcode p_code, char *p_srcFile, int p_srcLine,
59 /*@only@*/ cstring p_s,
60 /*@temp@*/ cstring p_addtext,
61 fileloc p_fl, bool p_iserror, bool p_indent)
80489f0a 62 /*@modifies g_warningstream@*/ ;
28bf4b0b 63
53306cab 64static void generateCSV (flagcode p_code, cstring p_s, cstring p_addtext, fileloc p_fl)
65 /*@modifies g_csvstream@*/ ;
66
616915dd 67static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
68 /*@globals lastfileloclen @*/
69 /*@modifies *p_stream@*/ ;
70static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
71 /*@modifies *p_stream@*/ ;
72
80489f0a 73static void llgenhint (/*@only@*/ cstring p_s) /*@modifies g_warningstream@*/ ;
28bf4b0b 74
75static void showSourceLoc (char *srcFile, int srcLine)
80489f0a 76 /*@modifies g_warningstream@*/
28bf4b0b 77{
78 if (context_getFlag (FLG_SHOWSOURCELOC)) {
79 llgenhint (message ("%s:%d: Source code error generation point.",
80 cstring_fromChars (srcFile), srcLine));
81 }
82
83}
84
616915dd 85static /*@null@*/ char *
86maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
87{
88 if (a > b) return a;
89 else return b;
90}
91
92static void
93printBugReport (void)
94{
80489f0a 95 fprintf (g_errorstream, " *** Please report bug to %s ***\n",
1b8ae690 96 SPLINT_MAINTAINER);
616915dd 97 llflush ();
98 /* don't exit (EXIT_FAILURE); */
99}
100
101static bool s_needsPrepare = TRUE;
102
80489f0a 103void prepareMessage ()
616915dd 104{
990ec868 105 DPRINTF (("Prepare message: %s", bool_unparse (context_loadingLibrary ())));
f2b6724f 106 showHerald ();
990ec868 107
108 if ((context_isPreprocessing () || context_loadingLibrary ())
616915dd 109 && s_needsPrepare
80489f0a 110 && context_getFlag (FLG_SHOWSCAN))
616915dd 111 {
112 llflush ();
80489f0a 113 displayScanClose ();
616915dd 114 s_needsPrepare = FALSE;
115 }
116
117 llflush ();
118}
119
120void closeMessage (void)
121{
122 if (context_isPreprocessing ()
80489f0a 123 && context_getFlag (FLG_SHOWSCAN))
616915dd 124 {
125 llflush ();
6fcd0b1e 126 displayScanOpen (cstring_makeLiteral ("more preprocessing ."));
28bf4b0b 127 llassertprotect (!s_needsPrepare);
616915dd 128 s_needsPrepare = TRUE;
129 }
130 else
131 {
132 llflush ();
133 }
134}
135
136void
137llmsg (/*@only@*/ cstring s)
138{
139 context_setNeednl ();
140 prepareMessage ();
80489f0a 141 printMessage (g_messagestream, s);
616915dd 142 closeMessage ();
143}
144
145void
146lldiagmsg (/*@only@*/ cstring s)
147{
982cc10b 148 static bool inmsg = FALSE;
149
150 if (inmsg)
151 {
80489f0a 152 fprintf (g_errorstream,
153 "Recursive message call detected: %s\n",
154 cstring_toCharsSafe (s));
982cc10b 155 llexit (LLFAILURE);
156 }
157
158 inmsg = TRUE;
159
616915dd 160 context_setNeednl ();
161 prepareMessage ();
80489f0a 162 printMessage (g_messagestream, s);
616915dd 163 closeMessage ();
982cc10b 164
165 inmsg = FALSE;
616915dd 166}
167
168void
169llmsgplain (/*@only@*/ cstring s)
170{
171 context_setNeednl ();
172 prepareMessage ();
80489f0a 173 printMessage (g_messagestream, s);
616915dd 174 closeMessage ();
175}
176
f3f2d5ea 177void llerror_flagWarning (cstring s)
616915dd 178{
179 if (context_getFlag (FLG_WARNFLAGS))
180 {
140c27a8 181 llgenmsg (s, g_currentloc);
616915dd 182 }
f3f2d5ea 183 else
184 {
185 cstring_free (s);
186 }
616915dd 187}
188
189static void
80489f0a 190llgenhint (/*@only@*/ cstring s) /*@modifies g_warningstream@*/
616915dd 191{
28bf4b0b 192 int indent = context_getIndentSpaces () - 1;
193
194 if (indent < 0) indent = 0;
195
616915dd 196 context_setNeednl ();
80489f0a 197 printIndentMessage (g_warningstream, s, indent);
616915dd 198}
199
200void
201llhint (cstring s)
202{
203 if (context_getFlag (FLG_HINTS) &&
204 !(context_inSuppressRegion () || context_inSuppressZone (g_currentloc)))
205 {
206 llgenhint (s);
207 }
208 else
209 {
210 cstring_free (s);
211 }
212}
213
214static void
215llshowhint (flagcode f)
216{
217 if (context_getFlag (FLG_HINTS))
218 {
219 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
220 {
221 cstring desc = flagcodeHint (f);
222
223 if (cstring_isDefined (desc))
224 {
225 llgenhint (cstring_copy (desc));
226 }
227 }
228 }
229}
230
28bf4b0b 231static void
232llsuppresshint2 (char c, flagcode f1, flagcode f2)
233{
234
235 if (context_getFlag (FLG_HINTS))
236 {
237 if ((flagcode_numReported (f1) == 0
238 || flagcode_numReported (f2) == 0)
239 || context_getFlag (FLG_FORCEHINTS))
240 {
241 cstring desc = flagcodeHint (f1);
242 context_setNeednl ();
243 lastfileloclen = 8;
244
245 if (cstring_isUndefined (desc))
246 {
247 desc = flagcodeHint (f2);
248 }
249
250 if (flagcode_isNamePrefixFlag (f1))
251 {
252 f1 = FLG_NAMECHECKS;
253 }
254
255 if (flagcode_isNamePrefixFlag (f2))
256 {
257 f2 = FLG_NAMECHECKS;
258 }
259
abb1cb43 260 if (f1 == f2)
28bf4b0b 261 {
abb1cb43 262 if (cstring_isDefined (desc))
263 {
2e127cb8 264 llgenhint (message ("%s (Use %h%s to inhibit warning)", desc,
abb1cb43 265 c,
266 flagcode_unparse (f1)));
267 }
268 else
269 {
2e127cb8 270 llgenhint (message ("(Use %h%s to inhibit warning)",
abb1cb43 271 c, flagcode_unparse (f1)));
272 }
28bf4b0b 273 }
274 else
275 {
abb1cb43 276 if (cstring_isDefined (desc))
277 {
2e127cb8 278 llgenhint (message ("%s (Use either %h%s or %h%s to inhibit warning)", desc,
abb1cb43 279 c,
280 flagcode_unparse (f1),
281 c,
282 flagcode_unparse (f2)));
283 }
284 else
285 {
2e127cb8 286 llgenhint (message ("(Use either %h%s or %h%s to inhibit warning)", c,
abb1cb43 287 flagcode_unparse (f1),
288 c, flagcode_unparse (f2)));
289 }
28bf4b0b 290 }
291 }
292 }
293}
616915dd 294
295static void
296llsuppresshint (char c, flagcode f)
297{
616915dd 298 if (context_getFlag (FLG_HINTS))
299 {
300 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
301 {
302 cstring desc = flagcodeHint (f);
303 context_setNeednl ();
304 lastfileloclen = 8;
305
306 if (flagcode_isNamePrefixFlag (f))
307 {
308 f = FLG_NAMECHECKS;
309 }
310
311 if (cstring_isDefined (desc))
312 {
2e127cb8 313 llgenhint (message ("%s (Use %h%s to inhibit warning)", desc, c,
28bf4b0b 314 flagcode_unparse (f)));
616915dd 315 }
316 else
317 {
2e127cb8 318 llgenhint (message ("(Use %h%s to inhibit warning)", c,
28bf4b0b 319 flagcode_unparse (f)));
616915dd 320 }
321 }
322 }
323}
324
325static void
326llnosuppresshint (flagcode f)
327{
616915dd 328 if (context_getFlag (FLG_FORCEHINTS))
329 {
330 cstring desc = flagcodeHint (f);
331 context_setNeednl ();
332 lastfileloclen = 8;
333
334 if (cstring_isDefined (desc))
335 {
80489f0a 336 printError (g_warningstream, message (" %s", desc));
616915dd 337 }
338 }
339}
340
341/*@constant int MAXSEARCH; @*/
342# define MAXSEARCH 20
343
344/*@constant int MINLINE; @*/
345# define MINLINE 35
346
347typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
348
349static void
350mstring_split (/*@returned@*/ char **sp,
351 /*@out@*/ nd_charp *tp,
352 int maxline, /*@in@*/ int *indentchars)
353{
354 char *nl;
355 char *t;
356 char *s = *sp;
28bf4b0b 357 char *osp = *sp;
616915dd 358
359 *tp = NULL;
360
28bf4b0b 361 DPRINTF (("Split: %s / %d", *sp, maxline));
362
616915dd 363 if (maxline < MINLINELEN)
364 {
365 maxline = MINLINELEN;
366 }
367
368 if (*indentchars > 0)
369 {
370 s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
28bf4b0b 371 osp = s;
616915dd 372 }
373
374 nl = strchr (s, '\n');
375
376 /*
377 ** splitting:
378 **
379 ** if there is a newline in first maxline characters, split there
380 ** if line len is <= maxline, return no split
21f0106c 381 ** if there is a ':' or ';' or ',' followed by ' ' in first maxline characters,
616915dd 382 ** split there unless the ' ' is followed by a '}', then
383 ** split after '}'
384 ** of the ';' is inside quotation marks
385 ** if there is a space or tab in last maxsearch characters, split there
386 ** else, split at maxline
387 **
388 ** special code: slash [1-9] after a newline means indent the rest <n> chars
389 **
390 */
391
392 if ((nl != NULL) && ((nl - s) < maxline))
393 {
394 *nl = '\0';
395 t = nl + 1;
396
397 if (*t == '\0')
398 {
28bf4b0b 399 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 400 return;
401 }
402
403 if (*t >= '\1' && *t <= '\7')
404 {
405 *indentchars += (int) (*t - '\1') + 1;
406 t++;
28bf4b0b 407 }
408
616915dd 409 *tp = t;
410 return;
411 }
412 else if (size_toInt (strlen (s)) < maxline)
413 {
28bf4b0b 414 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 415 return;
416 }
417 else
418 {
419 int i = 0;
420 char savechar;
21f0106c 421 char *lcolon, *lsemi, *lcomma;
422 char *splitat;
423
616915dd 424 splitat = NULL;
425
426 t = s + maxline - 1;
427 savechar = *t;
428
429 *t = '\0';
430 lcolon = strrchr (s, ':');
431 lsemi = strrchr (s, ';');
21f0106c 432 lcomma = strrchr (s, ',');
433
616915dd 434 *t = savechar;
435
436 splitat = maxcp (lcolon, lsemi);
437
438 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
28bf4b0b 439 && *(splitat) != '\0'
440 && *(splitat + 1) == ' '
21f0106c 441 && (*(splitat + 2) != '}'
442 && *(splitat + 2) != ','
443 && (*(splitat + 2) != '\0')))
616915dd 444 {
445 *(splitat + 1) = '\0';
446 t = splitat + 2;
447 *tp = t;
28bf4b0b 448 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 449 return;
450 }
451
21f0106c 452 if (lcomma != NULL && ((lcomma - s) > maxline - 5))
453 {
454 splitat = lcomma;
455
456 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
457 && *(splitat) != '\0'
458 && *(splitat + 1) == ' '
459 && (*(splitat + 2) != '}'
460 && (*(splitat + 2) != '\0')))
461 {
462 *(splitat + 1) = '\0';
463 t = splitat + 2;
464 *tp = t;
465 llassertprotect (*tp == NULL || (*tp > osp));
466 return;
467 }
468 }
469
616915dd 470 while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
471 {
472 t--;
473 i++;
474 }
475
476 if (*t != ' ' && *t != '\t')
477 {
28bf4b0b 478 llassertprotect (maxline > 0);
616915dd 479 t = mstring_copy (s + maxline);
480 *(s + maxline) = '\0';
481
482 if (*t == '\0')
483 {
484 sfree (t);
28bf4b0b 485 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 486 return;
487 }
488
489 mstring_markFree (t);
490 *tp = t;
28bf4b0b 491 /* Won't be true since t is a copy: llassertprotect (*tp == NULL || (*tp > osp)); */
616915dd 492 return;
493 }
494 else
495 {
28bf4b0b 496
616915dd 497 *t = '\0';
498 t++;
28bf4b0b 499
616915dd 500 if (*t == '\0') return;
501
502 /*
503 ** returns unqualified as only
504 */
505
506 *tp = t;
28bf4b0b 507
508# if 0
509 /* Hack to prevent error case for wierd strings. */
510 if (t <= osp)
511 {
512 *tp = NULL;
513 return;
514 }
515 llassertprotect (*tp == NULL || (*tp > osp));
516# endif
517
616915dd 518 return;
519 }
520 }
28bf4b0b 521
522 BADBRANCH;
616915dd 523}
524
525static
526void limitmessage (/*@only@*/ cstring s, fileloc loc)
527{
528 if (mcount > context_getLimit () + 1)
529 {
530 cstring_free (s);
531 }
532 else
533 {
534 cstring flstring = fileloc_unparse (loc);
535
536 lastfileloclen = cstring_length (flstring);
537 cstring_free (saveOneMessage);
538 saveOneMessage = message ("%q: %q", flstring, s);
539 }
540}
541
542static int parseerrorcount = 0;
543
544void cleanupMessages ()
545{
546 parseerrorcount = 0;
547
548 if (context_unlimitedMessages ())
549 {
550 ;
551 }
552 else
553 {
554 int unprinted = mcount - context_getLimit ();
555
556 if (unprinted > 0)
557 {
558 if (unprinted == 1 && cstring_isDefined (saveOneMessage))
559 {
560 prepareMessage ();
80489f0a 561 printError (g_warningstream, saveOneMessage);
616915dd 562 closeMessage ();
563 saveOneMessage = cstring_undefined;
564 }
565 else
566 {
567 if (cstring_isDefined (saveOneMessage))
568 {
569 /* cstring_free (saveOneMessage); */
570 saveOneMessage = cstring_undefined;
571 }
572
80489f0a 573 fprintf (g_warningstream, "%s: (%d more similar errors unprinted)\n",
616915dd 574 cstring_toCharsSafe (fileloc_filename (g_currentloc)),
575 mcount - context_getLimit ());
576 }
577 }
578 }
579
580 mcount = 0;
581}
582
583void
584llgenmsg (/*@only@*/ cstring s, fileloc fl)
585{
586 cstring flstring = fileloc_unparse (fl);
587 lastfileloclen = cstring_length (flstring);
588
589 prepareMessage ();
80489f0a 590 (void) printError (g_warningstream, message ("%q: %q", flstring, s));
616915dd 591 closeMessage ();
592}
593
594void
595llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
596{
597 cstring flstring = fileloc_unparse (fl);
16c024b5 598 int indentspaces = context_getLocIndentSpaces ();
616915dd 599 prepareMessage ();
16c024b5 600
601 (void) printIndentMessage (g_warningstream, message ("%q: %q", flstring, s),
602 indentspaces);
603
616915dd 604 closeMessage ();
605}
606
607void
608llgenindentmsgnoloc (/*@only@*/ cstring s)
609{
610 prepareMessage ();
80489f0a 611 (void) printIndentMessage (g_warningstream, s, context_getIndentSpaces ());
616915dd 612 closeMessage ();
613}
614
615static bool
28bf4b0b 616llgentypeerroraux (char *srcFile, int srcLine,
617 flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
618 /*@only@*/ cstring s, fileloc fl)
616915dd 619{
620 cstring hint = cstring_undefined;
621 flagcode code = ocode;
622 flagcode hcode = INVALID_FLAG;
623 ctype ut1 = t1;
624 ctype ut2 = t2;
625
990ec868 626 DPRINTF (("Type error [%s]: %s / %s : %s / %s",
627 flagcode_unparse (ocode),
616915dd 628 exprNode_unparse (e1), exprNode_unparse (e2),
629 ctype_unparse (t1), ctype_unparse (t2)));
630
631 DPRINTF (("Bool: %s / %s",
632 bool_unparse (ctype_isBool (t1)),
633 bool_unparse (ctype_isBool (t2))));
634
635 /*
636 ** Set the flag using the underlying types that didn't match.
637 */
638
639 while (ctype_isPointer (ut1) && ctype_isPointer (ut2)) {
640 ut1 = ctype_baseArrayPtr (ut1);
641 ut2 = ctype_baseArrayPtr (ut2);
642 }
643
e5081f8c 644 if (ctype_isRealNumAbstract (ut1) && exprNode_isNumLiteral (e2))
645 {
646 hcode = FLG_NUMABSTRACTLIT;
647 }
648 else if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
649 || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
616915dd 650 {
651 hcode = FLG_FLOATDOUBLE;
652 }
e5081f8c 653 else if ((exprNode_isCharLiteral (e1) && ctype_isInt (ut2))
654 || (exprNode_isCharLiteral (e2) && ctype_isInt (ut1)))
616915dd 655 {
656 hcode = FLG_CHARINTLITERAL;
657 }
e5081f8c 658 else if ((exprNode_isNumLiteral (e1) && ctype_isReal (ut2))
659 || (exprNode_isNumLiteral (e2) && ctype_isReal (ut1)))
616915dd 660 {
661 hcode = FLG_NUMLITERAL;
662 }
663 else if ((ctype_isManifestBool (ut1) && ctype_isInt (ut2))
664 || (ctype_isInt (ut1) && ctype_isManifestBool (ut2)))
665 /* evs 2000-07-24: was ctype_isDirectBool */
666 {
667 hcode = FLG_BOOLINT;
668 }
669 else if (((ctype_isChar (ut1) && !ctype_isInt (ut1)) && ctype_isInt (ut2))
670 || ((ctype_isInt (ut1) && (ctype_isChar (ut2) && !ctype_isInt (ut2)))))
671 {
672 hcode = FLG_CHARINT;
673 }
674 else if ((ctype_isInt (ut1) && ctype_isInt (ut2))
675 || (ctype_isChar (ut1) && ctype_isChar (ut2))
676 || (ctype_isDouble (ut1) && ctype_isDouble (ut2)))
677 {
678 if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
679 {
6fcd0b1e 680 if (ctype_isArbitraryIntegral (ctype_realType (ut1))
681 && !ctype_isArbitraryIntegral (ctype_realType (ut2)))
682 {
683 hcode = FLG_MATCHANYINTEGRAL;
684 }
685 else if (ctype_isArbitraryIntegral (ctype_realType (ut2))
686 && !ctype_isArbitraryIntegral (ctype_realType (ut1)))
687 {
688 hcode = FLG_MATCHANYINTEGRAL;
689 }
690 else
691 {
692 hcode = FLG_IGNORESIGNS;
693 }
616915dd 694 }
695 else
696 {
697 hcode = FLG_IGNOREQUALS;
698 }
699 }
700 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
701 {
702 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
703 {
704 hcode = FLG_MATCHANYINTEGRAL;
705 }
706 else if (ctype_match (ut2, ctype_ulint))
707 {
708 hcode = FLG_LONGUNSIGNEDINTEGRAL;
709 }
710 else if (ctype_match (ut2, ctype_lint))
711 {
712 hcode = FLG_LONGINTEGRAL;
713 }
714 else if (ctype_isInt (ut2))
715 {
716 hcode = FLG_MATCHANYINTEGRAL;
717 }
718 else
719 {
720 ;
721 }
722 }
723 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
724 {
725 ctype tr = ctype_realType (ut1);
726
727 if (ctype_isArbitraryIntegral (tr))
728 {
729 hcode = FLG_MATCHANYINTEGRAL;
730 }
731 else if (ctype_match (ut1, ctype_ulint))
732 {
733 if (ctype_isUnsignedIntegral (tr))
734 {
735 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
736 }
737 else if (ctype_isSignedIntegral (tr))
738 {
739 ;
740 }
741 else
742 {
743 hcode = FLG_LONGUNSIGNEDINTEGRAL;
744 }
745 }
746 else if (ctype_match (ut1, ctype_lint))
747 {
748 if (ctype_isSignedIntegral (tr))
749 {
750 hcode = FLG_LONGSIGNEDINTEGRAL;
751 }
752 else if (ctype_isSignedIntegral (tr))
753 {
754 ;
755 }
756 else
757 {
758 hcode = FLG_LONGINTEGRAL;
759 }
760 }
761 else if (ctype_isInt (ut1))
762 {
763 hcode = FLG_MATCHANYINTEGRAL;
764 }
765 else
766 {
767 ;
768 }
769 }
990ec868 770 else
771 {
772 ;
773 }
774
775 if (hcode == INVALID_FLAG)
616915dd 776 {
990ec868 777 DPRINTF (("[%s] %s - %s / %s",
778 ctype_unparse (ut1),
779 bool_unparse (ctype_isEnum (ut1)),
780 bool_unparse (ctype_isEnum (ctype_realType (ut1))),
781 bool_unparse (ctype_isInt (ut2))));
616915dd 782
990ec868 783 if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
616915dd 784 {
990ec868 785 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
786 ctype ct = uentry_getType (ue1);
787
788 if (ctype_match (ct, ut2))
789 {
790 code = FLG_ABSTRACT;
791 hint = message ("Underlying types match, but %s is an "
792 "abstract type that is not accessible here.",
793 ctype_unparse (t1));
794 }
616915dd 795 }
990ec868 796 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
797 {
798 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
799 ctype ct = uentry_getType (ue);
800
801 if (ctype_match (ct, ut1))
802 {
e5081f8c 803 if (ctype_isNumAbstract (ut2))
804 {
805 if (exprNode_isNumLiteral (e1))
806 {
807 code = FLG_NUMABSTRACTLIT;
808 hint = message ("Underlying types match, but %s is a "
809 "numabstract type that is not accessible here. "
810 "(Use +numabstractlit to allow numeric literals "
811 "to be used as numabstract type values.)",
812 ctype_unparse (t2));
813 }
814 else
815 {
816 code = FLG_NUMABSTRACT;
817 hint = message ("Underlying types match, but %s is a "
818 "numabstract type that is not accessible here.",
819 ctype_unparse (t2));
820 }
821 }
822 else
823 {
824 code = FLG_ABSTRACT;
825 hint = message ("Underlying types match, but %s is an "
826 "abstract type that is not accessible here.",
827 ctype_unparse (t2));
828 }
990ec868 829 }
830 }
831 else
832 {
833 ; /* Not an abstract mismatch. */
834 }
835
616915dd 836
990ec868 837 if (hcode == INVALID_FLAG)
616915dd 838 {
990ec868 839 if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
840 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
841 {
842 hcode = FLG_ENUMINT;
843 }
844 else if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
845 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
846 {
847 hcode = FLG_ENUMINT;
848 }
849 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
850 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
851 {
852 hcode = FLG_CHARUNSIGNEDCHAR;
853 }
854 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
855 {
856 hcode = FLG_RELAXTYPES;
857 DPRINTF (("Setting relax types!"));
858 }
859 else
860 {
861 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
862 ctype_unparse (ut2)));
863 }
616915dd 864 }
865 }
616915dd 866
867 if (cstring_isDefined (hint))
868 {
869 if (!context_suppressFlagMsg (ocode, fl))
870 {
e5081f8c 871 return xllgenhinterror (srcFile, srcLine, code, s, hint, fl);
616915dd 872 }
873 else
874 {
875 cstring_free (s);
876 cstring_free (hint);
877 return FALSE;
878 }
879 }
880 else
881 {
53306cab 882 if (hcode != INVALID_FLAG && hcode != ocode)
883 {
884 code = hcode;
885 }
886
e5081f8c 887 if (llgenerroraux (ocode, srcFile, srcLine, s,
888 flagcodeHint (code), fl, TRUE, FALSE))
616915dd 889 {
53306cab 890 if (code != ocode)
616915dd 891 {
6fcd0b1e 892 if (context_flagOn (code, fl))
893 {
894 /* The flag is alreay set, something buggy in the flag code */
895 llcontbug (message ("No hint available, flag %s is already set.",
896 flagcode_unparse (code)));
897 }
898 else
899 {
900 llshowhint (code);
901 }
53306cab 902 }
616915dd 903 else
904 {
905 llsuppresshint ('-', code);
906 }
907
908 flagcode_recordError (code);
909 return TRUE;
910 }
911
912 return FALSE;
913 }
914}
915
916bool
28bf4b0b 917xllgentypeerror (char *srcFile, int srcLine,
918 ctype t1, exprNode e1, ctype t2, exprNode e2,
919 /*@only@*/ cstring s, fileloc fl)
616915dd 920{
28bf4b0b 921 return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
616915dd 922}
923
924bool
28bf4b0b 925xllgenformattypeerror (char *srcFile, int srcLine,
926 ctype t1, exprNode e1, ctype t2, exprNode e2,
927 /*@only@*/ cstring s, fileloc fl)
616915dd 928{
ccf0a4a8 929 if (!context_suppressFlagMsg (FLG_FORMATTYPE, fl))
930 {
b73d1009 931 if (ctype_isInt (t1)
932 && ctype_isNumAbstract (t2))
933 {
934 if (!context_suppressFlagMsg (FLG_NUMABSTRACTPRINT, fl))
935 {
936 return llgentypeerroraux (srcFile, srcLine, FLG_NUMABSTRACTPRINT, t1, e1, t2, e2, s, fl);
937 }
938 else
939 {
940 return FALSE;
941 }
942 }
943 else
944 {
945 return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
946 }
ccf0a4a8 947 }
948 else
949 {
950 cstring_free (s);
951 return FALSE;
952 }
616915dd 953}
954
955bool
28bf4b0b 956xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
616915dd 957{
53306cab 958 if (llgenerroraux (o, srcFile, srcLine, s, flagcodeHint (o), fl, TRUE, FALSE))
616915dd 959 {
960 llnosuppresshint (o);
961 flagcode_recordError (o);
962 closeMessage ();
963 return TRUE;
964 }
965 else
966 {
967 flagcode_recordSuppressed (o);
968 return FALSE;
969 }
970}
971
972bool
28bf4b0b 973xllgenhinterror (char *srcFile, int srcLine,
974 flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
975 fileloc fl)
616915dd 976{
977 if (!context_suppressFlagMsg (o, fl))
978 {
53306cab 979 if (llgenerroraux (o, srcFile, srcLine, s, hint, fl, TRUE, FALSE))
616915dd 980 {
981 flagcode_recordError (o);
982
983 if (context_getFlag (FLG_HINTS))
984 {
985 llgenhint (hint);
986 }
987 else
988 {
989 cstring_free (hint);
990 }
991
992 closeMessage ();
993 return TRUE;
994 }
995
996 cstring_free (hint);
997 }
998 else
999 {
1000 cstring_free (hint);
1001 cstring_free (s);
1002 }
1003
1004 flagcode_recordSuppressed (o);
1005 return FALSE;
1006}
1007
1008static bool
53306cab 1009llrealerror (flagcode code, char *srcFile, int srcLine, /*@only@*/ cstring s, /*@temp@*/ cstring addtext, fileloc fl)
616915dd 1010{
53306cab 1011 return (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, TRUE, FALSE));
616915dd 1012}
1013
1014static bool
53306cab 1015llgenerroraux (flagcode code,
1016 char *srcFile, int srcLine,
1017 /*@only@*/ cstring s,
1018 cstring addtext,
1019 fileloc fl, bool iserror, bool indent)
616915dd 1020{
616915dd 1021 if (context_inSuppressZone (fl))
1022 {
1023 cstring_free (s);
1024 return FALSE;
1025 }
ccf0a4a8 1026
53306cab 1027 if (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, iserror, indent)) {
28bf4b0b 1028 return TRUE;
1029 } else {
1030 return FALSE;
1031 }
616915dd 1032}
1033
28bf4b0b 1034bool
1035xllforceerror (char *srcFile, int srcLine,
1036 flagcode code, /*@only@*/ cstring s, fileloc fl)
616915dd 1037{
1038 flagcode_recordError (code);
28bf4b0b 1039
53306cab 1040 if (llgenerrorreal (code, srcFile, srcLine, s, cstring_undefined, fl, TRUE, FALSE)) {
28bf4b0b 1041 closeMessage ();
1042 return TRUE;
1043 } else {
1044 return FALSE;
1045 }
616915dd 1046}
1047
53306cab 1048static void generateCSV (flagcode code, cstring s, cstring addtext, fileloc fl)
1049{
1050
1051 if (g_csvstream != NULL) {
1052 /* Warning, Flag Code, Flag Name, Priority, File, Line, Column, Warning Text, Additional Text */
1053 fprintf (g_csvstream, "%d,%d,%s,%d,%s,%d,%d,\"%s\"",
1054 context_numErrors (),
1055 (int) code, /* flag code */
1056 cstring_toCharsSafe (flagcode_unparse (code)), /* flag name */
1057 flagcode_priority (code), /* priority */
1058 cstring_toCharsSafe (fileloc_outputFilename (fl)),
1059 fileloc_lineno (fl),
1060 fileloc_column (fl),
1061 cstring_toCharsSafe (s));
1062
1063 if (cstring_isDefined (addtext)) {
1064 fprintf (g_csvstream, ",\"%s\"\n", cstring_toCharsSafe (addtext));
1065 } else {
1066 fprintf (g_csvstream, "\n");
1067 }
1068 }
1069}
1070
616915dd 1071static bool
53306cab 1072llgenerrorreal (flagcode code, char *srcFile, int srcLine,
1073 /*@only@*/ cstring s,
1074 cstring addtext,
1075 fileloc fl, bool iserror, bool indent)
616915dd 1076{
1077 cstring flstring;
1078
1079 /* duplicate message (rescanning a header file */
1080
1081 if (!messageLog_add (context_messageLog (), fl, s))
1082 {
28bf4b0b 1083 DPRINTF (("Duplicate message suppressed! %s / %s",
1084 fileloc_unparse (fl), s));
616915dd 1085 cstring_free (s);
1086 return FALSE;
1087 }
1088
60868d40 1089 /*
1090 ** If herald has not been displayed, display it before the first message.
1091 */
1092
1093 showHerald ();
1094
616915dd 1095 if (iserror) context_hasError ();
1096
1097 if (context_unlimitedMessages ())
1098 {
1099 ;
1100 }
1101 else
1102 {
1103 /*
1104 ** suppress excessive messages:
1105 ** check up to ':'
1106 **
1107 */
1108
1109 char *sc = cstring_toCharsSafe (s);
1110 char *tmpmsg = strchr (sc, ':');
1111
1112 if (tmpmsg == NULL)
1113 {
1114 tmpmsg = sc;
1115 }
1116 else
1117 {
1118 char *savechar = tmpmsg;
1119 *tmpmsg = '\0';
1120 tmpmsg = sc;
1121 *savechar = ':';
1122 }
1123
1124 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
1125 {
1126 mcount++;
1127 if (mcount == (context_getLimit () + 1))
1128 {
1129 limitmessage (s, fl);
1130 return FALSE;
1131 }
1132
1133 if (mcount > (context_getLimit ()))
1134 {
1135 cstring_free (s);
1136 return FALSE;
1137 }
1138 }
1139 else
1140 {
1141 cleanupMessages ();
1142 mcount = 0;
1143 cstring_free (lastmsg);
1144 lastmsg = cstring_fromCharsNew (tmpmsg);
1145 }
1146 }
1147
28bf4b0b 1148 DPRINTF (("Here..."));
1149
616915dd 1150 if (context_hasAliasAnnote ())
1151 {
1152 char *sc = cstring_toCharsSafe (s);
1153 char *fcolon = strchr (sc, ':');
1154 cstring a = context_getAliasAnnote ();
1155
1156
1157 if (fcolon == NULL)
1158 {
1159 s = message ("%q (%q)", s, a);
1160 }
1161 else
1162 {
1163 cstring afterColon;
1164
1165 *fcolon = '\0';
1166 afterColon = cstring_fromCharsNew (fcolon + 1);
1167
1168 s = message ("%q (%q):%q", s, a, afterColon);
1169 }
1170 }
1171
1172 if (context_hasMessageAnnote ())
1173 {
1174 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1175
1176
1177 if (fcolon == NULL)
1178 {
1179 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1180 s = message ("%q (%q)", s, context_getMessageAnnote ());
1181 /*@=dependenttrans@*/
1182 }
1183 else
1184 {
1185 cstring afterColon;
1186
1187 *fcolon = '\0';
1188 afterColon = cstring_fromCharsNew (fcolon + 1);
1189
1190 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1191 s = message ("%q (%q):%q", s,
1192 context_getMessageAnnote (), afterColon);
1193 /*@=dependenttrans@*/
1194 }
1195 }
1196
1197 context_setNeednl ();
1198 prepareMessage ();
1199
1200 if (context_showFunction ())
1201 {
1202 cstring fname = fileloc_unparseFilename (g_currentloc);
1203
1204 if (context_inIterDef ())
1205 {
80489f0a 1206 fprintf (g_warningstream, "%s: (in iter %s)\n",
616915dd 1207 cstring_toCharsSafe (fname),
1208 cstring_toCharsSafe (context_inFunctionName ()));
1209 }
1210 else if (context_inIterEnd ())
1211 {
80489f0a 1212 fprintf (g_warningstream, "%s: (in iter finalizer %s)\n",
616915dd 1213 cstring_toCharsSafe (fname),
1214 cstring_toCharsSafe (context_inFunctionName ()));
1215 }
1216 else if (context_inMacro ())
1217 {
80489f0a 1218 fprintf (g_warningstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
616915dd 1219 cstring_toCharsSafe (context_inFunctionName ()));
1220 }
1221 else
1222 {
80489f0a 1223 fprintf (g_warningstream, "%s: (in function %s)\n",
616915dd 1224 cstring_toCharsSafe (fname),
1225 cstring_toCharsSafe (context_inFunctionName ()));
1226 }
1227
1228 cstring_free (fname);
1229 context_setShownFunction ();
1230 }
1231
1232 flstring = fileloc_unparse (fl);
616915dd 1233 lastfileloclen = cstring_length (flstring);
1234
53306cab 1235 generateCSV (code, s, addtext, fl);
1236
616915dd 1237 if (indent)
1238 {
80489f0a 1239 printError (g_warningstream, message (" %q: %q", flstring, s));
616915dd 1240 }
1241 else
1242 {
80489f0a 1243 printError (g_warningstream, message ("%q: %q", flstring, s));
616915dd 1244 }
1245
28bf4b0b 1246 showSourceLoc (srcFile, srcLine);
53306cab 1247
616915dd 1248 return TRUE;
1249}
1250
1251/*
1252** printMessage
1253**
1254** message contains no '\n'
1255** message fits in one line: print it
1256** message fits in two lines with 3-space indent after fileloc: print it
1257** split line with 5-space indent from left margin: print it
1258**
1259*/
1260
1261static
1262void printMessage (FILE *stream, /*@only@*/ cstring s)
1263{
1264 printIndentMessage (stream, s, 0);
1265}
1266
1267static
1268void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1269{
28bf4b0b 1270 static bool inbody = FALSE;
616915dd 1271 int maxlen = context_getLineLen ();
1272 char *s = cstring_toCharsSafe (sc);
28bf4b0b 1273 char *olds = NULL;
616915dd 1274
28bf4b0b 1275 llassertprotect (!inbody);
1276 inbody = TRUE;
616915dd 1277
1278 do
1279 {
1280 char *t = NULL;
1281 char *st = s;
1282
28bf4b0b 1283 llassertprotect (st != olds);
1284 olds = st;
616915dd 1285 mstring_split (&st, &t, maxlen, &indent);
1286 fprintf (stream, "%s\n", st);
28bf4b0b 1287 llassertprotect (t != s);
616915dd 1288 s = t;
1289 } while (s != NULL) ;
1290
1291 cstring_free (sc);
28bf4b0b 1292 inbody = FALSE;
616915dd 1293}
1294
1295static
1296void printError (FILE *stream, /*@only@*/ cstring sc)
1297{
1298 int maxlen = context_getLineLen ();
abd7f895 1299 size_t nspaces = lastfileloclen + 5;
e5081f8c 1300 int nextlen = maxlen - size_toInt (nspaces);
abd7f895 1301 size_t len = cstring_length (sc);
616915dd 1302 int indent = 0;
1303 char *s = cstring_toCharsSafe (sc);
1304 char *os = s;
1305 char *t = NULL;
1306
28bf4b0b 1307 DPRINTF (("Print error: [%s]", sc));
1308
abd7f895 1309 if (size_toInt (len) < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
616915dd 1310 {
1311 mstring_split (&s, &t, maxlen, &indent);
1312
1313 fprintf (stream, "%s\n", s);
1314
1315 if (t != NULL)
1316 {
1317 len = mstring_length (t);
1318
abd7f895 1319 if (size_toInt (len) < (maxlen - 3) && (strchr (t, '\n') == NULL)
1320 && size_toInt (len) > (nextlen - 1))
616915dd 1321 {
1322 fprintf (stream, " %s\n", t);
1323 }
1324 else
1325 {
1326 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1327 int i;
1328
abd7f895 1329 for (i = 0; i < size_toInt (nspaces); i++)
616915dd 1330 {
1331 spaces[i] = ' ';
1332 }
1333
1334 spaces[nspaces] = '\0';
1335
1336 while (t != NULL)
1337 {
1338 char *st = t;
1339 mstring_split (&st, &t, nextlen, &indent);
1340 fprintf (stream, "%s%s\n", spaces, st);
1341 }
1342
1343 sfree (spaces);
1344 }
1345 }
1346 }
1347 else
1348 {
28bf4b0b 1349 DPRINTF (("Here 1: [%s]", sc));
1350
abd7f895 1351 if (size_toInt (len) < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
616915dd 1352 {
1353 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1354
1355 if (nspaces < 1) nspaces = 1;
1356
e5081f8c 1357 nextlen = size_toInt (maxlen - nspaces);
616915dd 1358
1359 mstring_split (&s, &t, maxlen, &indent);
1360
1361 fprintf (stream, "%s\n", s);
1362
1363 if (t != NULL)
1364 {
1365 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1366 int i;
1367
abd7f895 1368 for (i = 0; i < size_toInt (nspaces); i++)
616915dd 1369 {
1370 spaces[i] = ' ';
1371 }
1372
1373 spaces[nspaces] = '\0';
1374
1375 while (t != NULL)
1376 {
1377 char *st = t;
1378
1379 mstring_split (&st, &t, nextlen, &indent);
1380 fprintf (stream, "%s%s\n", spaces, st);
1381 }
1382
1383 sfree (spaces);
1384 }
1385 }
1386 else
1387 {
1388 nspaces = 4;
e5081f8c 1389 nextlen = size_toInt (maxlen - nspaces);
616915dd 1390
28bf4b0b 1391 DPRINTF (("Here 2: [%s]", s));
616915dd 1392 mstring_split (&s, &t, maxlen, &indent);
28bf4b0b 1393 DPRINTF (("Here 3: [%s] [%s]", s, t));
616915dd 1394
1395 fprintf (stream, "%s\n", s);
1396
1397 if (t != NULL)
1398 {
1399 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
abd7f895 1400 size_t i;
616915dd 1401
1402 for (i = 0; i < nspaces; i++)
1403 {
1404 spaces[i] = ' ';
1405 }
1406
1407 spaces[nspaces] = '\0';
1408
1409 while (t != NULL)
1410 {
1411 char *st = t;
28bf4b0b 1412 DPRINTF (("Loop: [%s]", t));
616915dd 1413 mstring_split (&st, &t, nextlen, &indent);
28bf4b0b 1414 DPRINTF (("Split: [%s] [%s]", st, t));
616915dd 1415 fprintf (stream, "%s%s\n", spaces, st);
28bf4b0b 1416 DPRINTF (("Next..."));
616915dd 1417 }
1418
1419 sfree (spaces);
1420 }
1421 }
1422 }
1423
28bf4b0b 1424 DPRINTF (("Done"));
616915dd 1425 sfree (os);
1426}
1427
1428void
28bf4b0b 1429xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1430{
1431 prepareMessage ();
80489f0a 1432 printError (g_errorstream, message ("%q: *** Fatal bug: %q",
1433 fileloc_unparse (g_currentloc), s));
28bf4b0b 1434 showSourceLoc (srcFile, srcLine);
616915dd 1435 printCodePoint ();
1436 printBugReport ();
1437 llexit (LLFAILURE);
1438}
1439
616915dd 1440void
1441lclfatalbug (char *msg)
1442{
1443 prepareMessage ();
80489f0a 1444 printError (g_errorstream,
616915dd 1445 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1446 printCodePoint ();
1447 printBugReport ();
1448 llexit (LLFAILURE);
1449}
616915dd 1450
1451void
1452checkParseError (void)
1453{
1454 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1455 {
1456 llfatalerror (message ("%q: Cannot recover from parse error.",
1457 fileloc_unparse (g_currentloc)));
1458 }
1459}
1460
1461void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1462{
1463 /*@unchecked@*/
1464 static int numbugs = 0;
1465 static bool inbug = FALSE;
1466
1467 if (inbug)
1468 {
1469 cstring temps = fileloc_unparseRaw (file, line);
1470
80489f0a 1471 fprintf (g_errorstream,
1472 "%s: Recursive bug detected: %s\n",
616915dd 1473 cstring_toCharsSafe (temps),
1474 cstring_toCharsSafe (s));
1475 cstring_free (temps);
1476
1477 llexit (LLFAILURE);
1478 }
1479
1480 inbug = TRUE;
1481
1482 prepareMessage ();
1483
616915dd 1484 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1485 {
1486 llfatalerror (message ("%q: Cannot recover from parse error.",
1487 fileloc_unparse (g_currentloc)));
1488 }
1489
80489f0a 1490 (void) fflush (g_warningstream);
abd7f895 1491
80489f0a 1492 printError (g_errorstream,
1493 message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1494 fileloc_unparse (g_currentloc),
1495 fileloc_unparseRaw (file, line),
1496 s, errno));
1497
abd7f895 1498 /* printCodePoint (); no longer useful */
616915dd 1499
80489f0a 1500 llflush ();
1501
6483a926 1502 /*
1503 ** This is confusing, and hardly ever useful.
1504
3120b462 1505 if (errno != 0)
1506 {
1507 perror ("Possible system error diagnostic: ");
1508 }
abd7f895 1509
6483a926 1510 **
1511 */
1512
616915dd 1513 printBugReport ();
80489f0a 1514 llflush ();
616915dd 1515
1516 numbugs++;
1517
28bf4b0b 1518 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
616915dd 1519 {
80489f0a 1520 llfatalerror
1521 (message ("%q: Cannot recover from last bug. "
1522 "(If you really want Splint to try to continue, use -bugslimit <n>.)",
1523 fileloc_unparse (g_currentloc)));
616915dd 1524 }
28bf4b0b 1525
80489f0a 1526 fprintf (g_errorstream, " (attempting to continue, results may be incorrect)\n");
616915dd 1527 fileloc_free (lastbug);
1528 lastbug = fileloc_copy (g_currentloc);
1529 closeMessage ();
616915dd 1530 inbug = FALSE;
1531}
1532
616915dd 1533void
1534lclbug (/*@only@*/ cstring s)
1535{
1536 prepareMessage ();
80489f0a 1537 printError (g_errorstream, message ("*** Internal Bug: %q", s));
616915dd 1538 printCodePoint ();
1539 printBugReport ();
80489f0a 1540 fprintf (g_errorstream, " (attempting to continue, results may be incorrect)\n");
616915dd 1541 closeMessage ();
1542}
616915dd 1543
1544void
01a8227e 1545xllfatalerror (char *srcFile, int srcLine, cstring s)
616915dd 1546{
1547 prepareMessage ();
80489f0a 1548 printError (g_errorstream, s);
1549 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
01a8227e 1550 showSourceLoc (srcFile, srcLine);
616915dd 1551 llexit (LLFAILURE);
1552}
1553
1554void
01a8227e 1555xllfatalerrorLoc (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1556{
1557 prepareMessage ();
80489f0a 1558 (void) fflush (g_warningstream);
1559 printError (g_errorstream, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1560 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
01a8227e 1561 showSourceLoc (srcFile, srcLine);
80489f0a 1562 (void) fflush (g_warningstream);
616915dd 1563 llexit (LLFAILURE);
1564}
1565
616915dd 1566bool
1567lclHadError (void)
1568{
1569 return (lclerrors > 0);
1570}
1571
1572bool
1573lclHadNewError (void)
1574{
1575 static int lastcall = 0;
1576
1577 if (lclerrors > lastcall)
1578 {
1579 lastcall = lclerrors;
1580 return TRUE;
1581 }
1582 else
1583 {
1584 return FALSE;
1585 }
1586}
1587
1588int
1589lclNumberErrors (void)
1590{
1591 return (lclerrors);
1592}
1593
1594void
28bf4b0b 1595xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
616915dd 1596{
1597 lclerrors++;
1598
1599 if (ltoken_getCode (t) != NOTTOKEN)
1600 {
1601 cstring loc = ltoken_unparseLoc (t);
616915dd 1602 lastfileloclen = cstring_length (loc);
1603
80489f0a 1604 printError (g_warningstream, message ("%q: %q", loc, msg));
28bf4b0b 1605 showSourceLoc (srcFile, srcLine);
616915dd 1606 }
1607 else
1608 {
80489f0a 1609 printError (g_warningstream, msg);
28bf4b0b 1610 showSourceLoc (srcFile, srcLine);
616915dd 1611 }
1612}
1613
1614void
1615lclplainerror (/*@only@*/ cstring msg)
1616{
1617 lclerrors++;
80489f0a 1618 printError (g_warningstream, msg);
616915dd 1619}
1620
1621void
1622lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1623{
80489f0a 1624 if (ltoken_getCode (t) != NOTTOKEN)
1625 {
1626 cstring loc = ltoken_unparseLoc (t);
1627 lastfileloclen = cstring_length (loc);
1628 printError (g_errorstream, message ("%q: %q", loc, msg));
1629 }
1630 else
1631 {
1632 printError (g_errorstream, msg);
1633 }
1634
1635 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue"));
616915dd 1636 llexit (LLFAILURE);
1637}
1638
1639void
1640lclplainfatalerror (/*@only@*/ cstring msg)
1641{
80489f0a 1642 (void) fflush (g_warningstream);
1643 printError (g_errorstream, message ("*** Cannot continue: %q", msg));
616915dd 1644 llexit (LLFAILURE);
1645}
1646
1647void
1648lclRedeclarationError (ltoken id)
1649{
1650 cstring s = ltoken_getRawString (id);
1651
1652
1653 if (usymtab_existsEither (s))
1654 {
1655 uentry le = usymtab_lookupEither (s);
1656
1657 lclerror (id, message ("Respecification of %s", s));
1658 llgenindentmsg (message ("Previous specification of %q",
1659 uentry_getName (le)),
1660 uentry_whereSpecified (le));
1661 }
1662 else
1663 {
1664 lclerror (id, message ("Identifier redeclared: %s", s));
1665 }
1666}
616915dd 1667
1668void genppllerror (flagcode code, /*@only@*/ cstring s)
1669{
1670 if (context_inSuppressZone (g_currentloc))
1671 {
1672 cstring_free (s);
1673 }
1674 else
1675 {
1676 if (context_getFlag (code))
1677 {
80489f0a 1678 if (!context_isInCommandLine ())
616915dd 1679 {
80489f0a 1680 displayScanClose ();
616915dd 1681 }
1682
1683 llerror (code, s);
1684
1685 if (code != FLG_PREPROC)
1686 {
1687 llsuppresshint ('-', code);
1688 }
1689
80489f0a 1690 if (!context_isInCommandLine ())
616915dd 1691 {
80489f0a 1692 displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
616915dd 1693 }
1694 }
1695 else
1696 {
1697 cstring_free (s);
1698 }
1699 }
1700}
1701
1702void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1703 /*@only@*/ cstring hint)
1704{
1705 if (context_inSuppressZone (g_currentloc))
1706 {
1707 cstring_free (s);
1708 cstring_free (hint);
1709 }
1710 else
1711 {
1712 if (context_getFlag (code))
1713 {
53306cab 1714 generateCSV (code, s, hint, g_currentloc);
616915dd 1715 prepareMessage ();
1716 context_clearPreprocessing ();
1717 llerror (code, s);
1718 llgenhint (hint);
1719 context_setPreprocessing ();
1720 closeMessage ();
1721 }
1722 else
1723 {
1724 cstring_free (s);
1725 cstring_free (hint);
1726 }
1727 }
1728}
1729
1730void ppllerror (/*@only@*/ cstring s)
1731{
1732 genppllerror (FLG_PREPROC, s);
1733}
1734
1735void pplldiagmsg (cstring s)
1736{
80489f0a 1737 if (!context_isInCommandLine ())
616915dd 1738 {
80489f0a 1739 displayScanClose ();
616915dd 1740 lldiagmsg (s);
80489f0a 1741 displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
616915dd 1742 }
1743 else
1744 {
1745 lldiagmsg (s);
1746 }
1747}
1748
1749void loadllmsg (cstring s)
1750{
80489f0a 1751 displayScanClose ();
1752 lldiagmsg (s);
1753 displayScanOpen (cstring_makeLiteral ("< ."));
616915dd 1754}
1755
1756static void llreportparseerror (/*@only@*/ cstring s)
1757{
1758 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1759 {
1760 cstring_free (s);
1761 }
1762 else
1763 {
1764 llerror (FLG_SYNTAX, s);
1765
1766 fileloc_free (lastparseerror);
1767 lastparseerror = fileloc_copy (g_currentloc);
1768 }
1769}
1770
b072092f 1771bool xcppoptgenerror (char *srcFile, int srcLine,
1772 flagcode o,
1773 /*@only@*/ cstring s,
1774 cppReader *pfile)
1775{
1776 bool res = FALSE;
1777 fileloc loc = cppReader_getLoc (pfile);
1778
1779 if (context_flagOn (o, loc))
1780 {
1781 if (xlloptgenerror (srcFile, srcLine, o, s, loc))
1782 {
1783 cppReader_printContainingFiles (pfile);
1784 res = TRUE;
1785 }
1786 }
1787 else
1788 {
1789 cstring_free (s);
1790 }
1791
1792 fileloc_free (loc);
1793
1794 return res;
1795}
1796
28bf4b0b 1797bool xlloptgenerror (char *srcFile, int srcLine,
1798 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1799{
28bf4b0b 1800 DPRINTF (("xllopt: %s", s));
1801
53306cab 1802 if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
616915dd 1803 {
28bf4b0b 1804 DPRINTF (("Here we are!"));
616915dd 1805 llsuppresshint ('-', o);
1806 closeMessage ();
1807 flagcode_recordError (o);
1808 return TRUE;
1809 }
28bf4b0b 1810 else
1811 {
1812 DPRINTF (("Suppressed!"));
1813 flagcode_recordSuppressed (o);
1814 return FALSE;
1815 }
616915dd 1816}
1817
28bf4b0b 1818bool xoptgenerror2 (char *srcFile, int srcLine,
1819 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1820{
1821 if (context_suppressFlagMsg (f1, loc))
1822 {
1823 flagcode_recordSuppressed (f1);
1824 cstring_free (s);
1825 }
1826 else
1827 {
1828 if (context_suppressFlagMsg (f2, loc))
1829 {
1830 flagcode_recordSuppressed (f2);
1831 cstring_free (s);
1832 }
1833 else
1834 {
53306cab 1835 if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f1), loc))
616915dd 1836 {
28bf4b0b 1837 llsuppresshint2 ('-', f1, f2);
616915dd 1838 flagcode_recordError (f2);
1839 closeMessage ();
1840 return TRUE;
1841 }
28bf4b0b 1842 else
1843 {
1844 flagcode_recordSuppressed (f2);
1845 }
616915dd 1846 }
1847 }
28bf4b0b 1848
616915dd 1849 return FALSE;
1850}
1851
28bf4b0b 1852bool xoptgenerror2n (char *srcFile, int srcLine,
1853 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1854{
1855
1856 if (context_suppressFlagMsg (f1, loc))
1857 {
1858 flagcode_recordSuppressed (f1);
1859 cstring_free (s);
1860 }
1861 else
1862 {
1863 if (context_suppressNotFlagMsg (f2, loc))
1864 {
1865 flagcode_recordSuppressed (f2);
1866 cstring_free (s);
1867 }
1868 else
1869 {
53306cab 1870 if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f2), loc))
616915dd 1871 {
1872 llsuppresshint ('+', f2);
1873 flagcode_recordError (f2);
1874 closeMessage ();
1875 return TRUE;
1876 }
1877
1878 flagcode_recordSuppressed (f2);
1879 }
1880 }
1881 return FALSE;
1882}
1883
28bf4b0b 1884bool xllnoptgenerror (char *srcFile, int srcLine,
1885 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1886{
53306cab 1887 if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
616915dd 1888 {
1889 llsuppresshint ('+', o);
1890 flagcode_recordError (o);
1891 closeMessage ();
1892 return TRUE;
1893 }
1894
1895 flagcode_recordSuppressed (o);
1896 return FALSE;
1897}
1898
01a8227e 1899void xllparseerror (char *srcFile, int srcLine, cstring s)
616915dd 1900{
1901 if (context_getFlag (FLG_TRYTORECOVER))
1902 {
1903 parseerrorcount++;
1904
1905 if (parseerrorcount > GIVEUPPARSE)
1906 {
1907 if (cstring_isDefined (s))
1908 {
01a8227e 1909 xllfatalerror (srcFile, srcLine,
1910 message ("%q: Parse Error: %q. "
1911 "Too many errors, giving up.",
1912 fileloc_unparse (g_currentloc), s));
616915dd 1913 }
1914 else
1915 {
01a8227e 1916 xllfatalerror (srcFile, srcLine,
1917 message ("%q: Parse Error. Too many errors, giving up.",
1918 fileloc_unparse (g_currentloc)));
616915dd 1919 }
1920 }
1921 else
1922 {
1923 if (cstring_isDefined (s))
1924 {
1925 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1926 s));
01a8227e 1927 showSourceLoc (srcFile, srcLine);
616915dd 1928 }
1929 else
1930 {
1931 llreportparseerror (message ("Parse Error. Attempting to continue."));
01a8227e 1932 showSourceLoc (srcFile, srcLine);
616915dd 1933 }
1934 }
1935 }
1936 else
1937 {
1938 cstring msg;
1939
1940 if (cstring_isDefined (s))
1941 {
1942 msg = message ("Parse Error: %q.", s);
1943 }
1944 else
1945 {
1946 msg = message ("Parse Error.");
1947 }
1948
01a8227e 1949 xllfatalerror
1950 (srcFile, srcLine,
1951 message ("%q: %s (For help on parse errors, "
1b8ae690 1952 "see splint -help parseerrors.)",
616915dd 1953 fileloc_unparse (g_currentloc), msg));
1954 }
1955}
1956
28bf4b0b 1957bool xfsgenerror (char *srcFile, int srcLine,
53306cab 1958 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
28bf4b0b 1959{
1960 if (flagSpec_isOn (fs, fl))
1961 {
53306cab 1962 flagcode firston = flagSpec_getFirstOn (fs, fl);
1963
1964 if (llgenerroraux (firston, srcFile, srcLine, s,
1965 flagcodeHint (firston),
1966 fl, TRUE, FALSE))
28bf4b0b 1967 {
53306cab 1968 llsuppresshint ('-', firston);
1969 flagcode_recordError (firston);
28bf4b0b 1970 return TRUE;
1971 }
1972 else
1973 {
53306cab 1974 flagcode_recordSuppressed (firston);
28bf4b0b 1975 return FALSE;
1976 }
1977 }
1978 else
1979 {
1980 flagcode_recordSuppressed (flagSpec_getDominant (fs));
1981 cstring_free (s);
1982 return FALSE;
1983 }
1984}
1985
616915dd 1986bool doCheck (bool x, cstring pred, cstring file, int line)
1987{
1988 if (!x) {
1989 llbug (message ("%q: Check Failed: %s",
1990 fileloc_unparseRaw (file, line),
1991 pred));
1992 }
1993
1994 return x;
1995}
1996
1997/*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1998{
1999 char *result;
2000
2001#ifndef VMS
2002#ifndef HAVE_STRERROR
2003 result = NULL;
2004#else
2005 result = strerror (errnum);
2006#endif
2007#else /* VMS */
2008 /* VAXCRTL's strerror() takes an optional second argument, which only
2009 matters when the first argument is EVMSERR. However, it's simplest
2010 just to pass it unconditionally. `vaxc$errno' is declared in
2011 <errno.h>, and maintained by the library in parallel with `errno'.
2012 We assume that caller's `errnum' either matches the last setting of
2013 `errno' by the library or else does not have the value `EVMSERR'. */
2014
2015 result = strerror (errnum, vaxc$errno);
2016#endif
2017
2018 if (result == NULL)
2019 {
2020 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
2021 }
2022
2023 return cstring_fromChars (result);
2024}
2025
2026void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
2027{
2028# if 0
2029# ifdef HOMEVERSION
2030 llflush ();
80489f0a 2031 printError (g_errorstream, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
2032 fileloc_unparse (g_currentloc),
2033 fileloc_unparseRaw (file, line),
2034 s, errno));
616915dd 2035 printCodePoint ();
2036 llflush ();
2037# endif
2038# else
2039 cstring_free (s);
2040# endif
2041}
2042
2043void llflush (void)
2044{
80489f0a 2045 (void) fflush (g_warningstream);
2046 (void) fflush (g_messagestream);
2047}
2048
2049static bool s_scanOpen = FALSE;
2050
2051void displayScan (cstring msg)
2052{
ce7034f0 2053 if (s_scanOpen)
2054 {
2055 displayScanClose ();
2056 }
2057
80489f0a 2058 llassert (!s_scanOpen);
2059
2060 if (context_getFlag (FLG_SHOWSCAN))
2061 {
ce7034f0 2062 showHerald ();
80489f0a 2063 fprintf (g_messagestream, "< %s >\n", cstring_toCharsSafe (msg));
2064 (void) fflush (g_messagestream);
2065 }
2066
2067 cstring_free (msg);
2068}
2069
2070void displayScanOpen (cstring msg)
2071{
ce7034f0 2072 if (s_scanOpen)
2073 {
2074 displayScanClose ();
2075 }
2076
80489f0a 2077 llassert (!s_scanOpen);
2078 s_scanOpen = TRUE;
2079
2080 if (context_getFlag (FLG_SHOWSCAN))
2081 {
2082 fprintf (g_messagestream, "< %s", cstring_toCharsSafe (msg));
2083 (void) fflush (g_messagestream);
2084 }
2085
2086 cstring_free (msg);
2087}
2088
2089void displayScanContinue (/*@temp@*/ cstring msg)
2090{
2091 if (context_getFlag (FLG_SHOWSCAN))
2092 {
6483a926 2093 if (s_scanOpen)
2094 {
2095 fprintf (g_messagestream, "%s", cstring_toCharsSafe (msg));
2096 (void) fflush (g_messagestream);
2097 }
2098 else
2099 {
2100 /*
2101 ** Don't call bug recursively
2102 */
2103
2104 fprintf (stderr, "*** Bug: scan continue scan not open\n");
2105 }
80489f0a 2106 }
2107}
2108
2109void displayScanClose (void)
2110{
6483a926 2111 if (s_scanOpen)
80489f0a 2112 {
6483a926 2113 if (context_getFlag (FLG_SHOWSCAN))
2114 {
2115 fprintf (g_messagestream, " >\n");
2116 (void) fflush (g_messagestream);
2117 }
80489f0a 2118 }
6483a926 2119 else
2120 {
2121 /*
2122 ** Don't call bug recursively
2123 */
2124
2125 fprintf (stderr, "*** Bug: scan close scan not open\n");
2126 }
2127
80489f0a 2128 s_scanOpen = FALSE;
616915dd 2129}
80489f0a 2130
2131
This page took 7.480584 seconds and 5 git commands to generate.