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