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