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