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