]> andersk Git - splint.git/blame - src/llerror.c
Fixed bug causing Splint is suggest using the +ignoresigns flag even if it was alread...
[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
1489 if (inbug)
1490 {
1491 cstring temps = fileloc_unparseRaw (file, line);
1492
80489f0a 1493 fprintf (g_errorstream,
1494 "%s: Recursive bug detected: %s\n",
616915dd 1495 cstring_toCharsSafe (temps),
1496 cstring_toCharsSafe (s));
1497 cstring_free (temps);
1498
1499 llexit (LLFAILURE);
1500 }
1501
1502 inbug = TRUE;
1503
1504 prepareMessage ();
1505
616915dd 1506 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1507 {
1508 llfatalerror (message ("%q: Cannot recover from parse error.",
1509 fileloc_unparse (g_currentloc)));
1510 }
1511
80489f0a 1512 (void) fflush (g_warningstream);
abd7f895 1513
80489f0a 1514 printError (g_errorstream,
1515 message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1516 fileloc_unparse (g_currentloc),
1517 fileloc_unparseRaw (file, line),
1518 s, errno));
1519
abd7f895 1520 /* printCodePoint (); no longer useful */
616915dd 1521
80489f0a 1522 llflush ();
1523
6483a926 1524 /*
1525 ** This is confusing, and hardly ever useful.
1526
3120b462 1527 if (errno != 0)
1528 {
1529 perror ("Possible system error diagnostic: ");
1530 }
abd7f895 1531
6483a926 1532 **
1533 */
1534
616915dd 1535 printBugReport ();
80489f0a 1536 llflush ();
616915dd 1537
1538 numbugs++;
1539
28bf4b0b 1540 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
616915dd 1541 {
80489f0a 1542 llfatalerror
1543 (message ("%q: Cannot recover from last bug. "
1544 "(If you really want Splint to try to continue, use -bugslimit <n>.)",
1545 fileloc_unparse (g_currentloc)));
616915dd 1546 }
28bf4b0b 1547
80489f0a 1548 fprintf (g_errorstream, " (attempting to continue, results may be incorrect)\n");
616915dd 1549 fileloc_free (lastbug);
1550 lastbug = fileloc_copy (g_currentloc);
1551 closeMessage ();
616915dd 1552 inbug = FALSE;
1553}
1554
616915dd 1555void
1556lclbug (/*@only@*/ cstring s)
1557{
1558 prepareMessage ();
80489f0a 1559 printError (g_errorstream, message ("*** Internal Bug: %q", s));
616915dd 1560 printCodePoint ();
1561 printBugReport ();
80489f0a 1562 fprintf (g_errorstream, " (attempting to continue, results may be incorrect)\n");
616915dd 1563 closeMessage ();
1564}
616915dd 1565
1566void
01a8227e 1567xllfatalerror (char *srcFile, int srcLine, cstring s)
616915dd 1568{
1569 prepareMessage ();
80489f0a 1570 printError (g_errorstream, s);
1571 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
01a8227e 1572 showSourceLoc (srcFile, srcLine);
616915dd 1573 llexit (LLFAILURE);
1574}
1575
1576void
01a8227e 1577xllfatalerrorLoc (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1578{
1579 prepareMessage ();
80489f0a 1580 (void) fflush (g_warningstream);
1581 printError (g_errorstream, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1582 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
01a8227e 1583 showSourceLoc (srcFile, srcLine);
80489f0a 1584 (void) fflush (g_warningstream);
616915dd 1585 llexit (LLFAILURE);
1586}
1587
616915dd 1588bool
1589lclHadError (void)
1590{
517a2db3 1591 return (s_lclerrors > 0);
616915dd 1592}
1593
1594bool
1595lclHadNewError (void)
1596{
1597 static int lastcall = 0;
1598
517a2db3 1599 if (s_lclerrors > lastcall)
616915dd 1600 {
517a2db3 1601 lastcall = s_lclerrors;
616915dd 1602 return TRUE;
1603 }
1604 else
1605 {
1606 return FALSE;
1607 }
1608}
1609
1610int
1611lclNumberErrors (void)
1612{
517a2db3 1613 return (s_lclerrors);
616915dd 1614}
1615
1616void
28bf4b0b 1617xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
616915dd 1618{
517a2db3 1619 s_lclerrors++;
616915dd 1620
1621 if (ltoken_getCode (t) != NOTTOKEN)
1622 {
1623 cstring loc = ltoken_unparseLoc (t);
517a2db3 1624 s_lastfileloclen = cstring_length (loc);
616915dd 1625
80489f0a 1626 printError (g_warningstream, message ("%q: %q", loc, msg));
28bf4b0b 1627 showSourceLoc (srcFile, srcLine);
616915dd 1628 }
1629 else
1630 {
80489f0a 1631 printError (g_warningstream, msg);
28bf4b0b 1632 showSourceLoc (srcFile, srcLine);
616915dd 1633 }
1634}
1635
1636void
1637lclplainerror (/*@only@*/ cstring msg)
1638{
517a2db3 1639 s_lclerrors++;
80489f0a 1640 printError (g_warningstream, msg);
616915dd 1641}
1642
1643void
1644lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1645{
80489f0a 1646 if (ltoken_getCode (t) != NOTTOKEN)
1647 {
1648 cstring loc = ltoken_unparseLoc (t);
517a2db3 1649 s_lastfileloclen = cstring_length (loc);
80489f0a 1650 printError (g_errorstream, message ("%q: %q", loc, msg));
1651 }
1652 else
1653 {
1654 printError (g_errorstream, msg);
1655 }
1656
1657 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue"));
616915dd 1658 llexit (LLFAILURE);
1659}
1660
1661void
1662lclplainfatalerror (/*@only@*/ cstring msg)
1663{
80489f0a 1664 (void) fflush (g_warningstream);
1665 printError (g_errorstream, message ("*** Cannot continue: %q", msg));
616915dd 1666 llexit (LLFAILURE);
1667}
1668
1669void
1670lclRedeclarationError (ltoken id)
1671{
1672 cstring s = ltoken_getRawString (id);
1673
1674
1675 if (usymtab_existsEither (s))
1676 {
1677 uentry le = usymtab_lookupEither (s);
1678
1679 lclerror (id, message ("Respecification of %s", s));
1680 llgenindentmsg (message ("Previous specification of %q",
1681 uentry_getName (le)),
1682 uentry_whereSpecified (le));
1683 }
1684 else
1685 {
1686 lclerror (id, message ("Identifier redeclared: %s", s));
1687 }
1688}
616915dd 1689
1690void genppllerror (flagcode code, /*@only@*/ cstring s)
1691{
1692 if (context_inSuppressZone (g_currentloc))
1693 {
1694 cstring_free (s);
1695 }
1696 else
1697 {
1698 if (context_getFlag (code))
1699 {
517a2db3 1700 if (s_scanOpen)
616915dd 1701 {
80489f0a 1702 displayScanClose ();
616915dd 1703 }
1704
1705 llerror (code, s);
1706
1707 if (code != FLG_PREPROC)
1708 {
1709 llsuppresshint ('-', code);
1710 }
1711
80489f0a 1712 if (!context_isInCommandLine ())
616915dd 1713 {
80489f0a 1714 displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
616915dd 1715 }
1716 }
1717 else
1718 {
1719 cstring_free (s);
1720 }
1721 }
1722}
1723
1724void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1725 /*@only@*/ cstring hint)
1726{
1727 if (context_inSuppressZone (g_currentloc))
1728 {
1729 cstring_free (s);
1730 cstring_free (hint);
1731 }
1732 else
1733 {
1734 if (context_getFlag (code))
1735 {
53306cab 1736 generateCSV (code, s, hint, g_currentloc);
616915dd 1737 prepareMessage ();
1738 context_clearPreprocessing ();
1739 llerror (code, s);
1740 llgenhint (hint);
1741 context_setPreprocessing ();
1742 closeMessage ();
1743 }
1744 else
1745 {
1746 cstring_free (s);
1747 cstring_free (hint);
1748 }
1749 }
1750}
1751
1752void ppllerror (/*@only@*/ cstring s)
1753{
1754 genppllerror (FLG_PREPROC, s);
1755}
1756
1757void pplldiagmsg (cstring s)
1758{
80489f0a 1759 if (!context_isInCommandLine ())
616915dd 1760 {
517a2db3 1761 if (s_scanOpen)
1762 {
1763 displayScanClose ();
1764 }
1765
616915dd 1766 lldiagmsg (s);
80489f0a 1767 displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
616915dd 1768 }
1769 else
1770 {
1771 lldiagmsg (s);
1772 }
1773}
1774
1775void loadllmsg (cstring s)
1776{
80489f0a 1777 displayScanClose ();
1778 lldiagmsg (s);
1779 displayScanOpen (cstring_makeLiteral ("< ."));
616915dd 1780}
1781
1782static void llreportparseerror (/*@only@*/ cstring s)
1783{
1784 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1785 {
1786 cstring_free (s);
1787 }
1788 else
1789 {
1790 llerror (FLG_SYNTAX, s);
1791
1792 fileloc_free (lastparseerror);
1793 lastparseerror = fileloc_copy (g_currentloc);
1794 }
1795}
1796
b072092f 1797bool xcppoptgenerror (char *srcFile, int srcLine,
1798 flagcode o,
1799 /*@only@*/ cstring s,
1800 cppReader *pfile)
1801{
1802 bool res = FALSE;
1803 fileloc loc = cppReader_getLoc (pfile);
1804
1805 if (context_flagOn (o, loc))
1806 {
1807 if (xlloptgenerror (srcFile, srcLine, o, s, loc))
1808 {
1809 cppReader_printContainingFiles (pfile);
1810 res = TRUE;
1811 }
1812 }
1813 else
1814 {
1815 cstring_free (s);
1816 }
1817
1818 fileloc_free (loc);
1819
1820 return res;
1821}
1822
28bf4b0b 1823bool xlloptgenerror (char *srcFile, int srcLine,
1824 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1825{
28bf4b0b 1826 DPRINTF (("xllopt: %s", s));
1827
53306cab 1828 if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
616915dd 1829 {
28bf4b0b 1830 DPRINTF (("Here we are!"));
616915dd 1831 llsuppresshint ('-', o);
1832 closeMessage ();
1833 flagcode_recordError (o);
1834 return TRUE;
1835 }
28bf4b0b 1836 else
1837 {
1838 DPRINTF (("Suppressed!"));
1839 flagcode_recordSuppressed (o);
1840 return FALSE;
1841 }
616915dd 1842}
1843
28bf4b0b 1844bool xoptgenerror2 (char *srcFile, int srcLine,
1845 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1846{
1847 if (context_suppressFlagMsg (f1, loc))
1848 {
1849 flagcode_recordSuppressed (f1);
1850 cstring_free (s);
1851 }
1852 else
1853 {
1854 if (context_suppressFlagMsg (f2, loc))
1855 {
1856 flagcode_recordSuppressed (f2);
1857 cstring_free (s);
1858 }
1859 else
1860 {
53306cab 1861 if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f1), loc))
616915dd 1862 {
28bf4b0b 1863 llsuppresshint2 ('-', f1, f2);
616915dd 1864 flagcode_recordError (f2);
1865 closeMessage ();
1866 return TRUE;
1867 }
28bf4b0b 1868 else
1869 {
1870 flagcode_recordSuppressed (f2);
1871 }
616915dd 1872 }
1873 }
28bf4b0b 1874
616915dd 1875 return FALSE;
1876}
1877
28bf4b0b 1878bool xoptgenerror2n (char *srcFile, int srcLine,
1879 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1880{
1881
1882 if (context_suppressFlagMsg (f1, loc))
1883 {
1884 flagcode_recordSuppressed (f1);
1885 cstring_free (s);
1886 }
1887 else
1888 {
1889 if (context_suppressNotFlagMsg (f2, loc))
1890 {
1891 flagcode_recordSuppressed (f2);
1892 cstring_free (s);
1893 }
1894 else
1895 {
53306cab 1896 if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f2), loc))
616915dd 1897 {
1898 llsuppresshint ('+', f2);
1899 flagcode_recordError (f2);
1900 closeMessage ();
1901 return TRUE;
1902 }
1903
1904 flagcode_recordSuppressed (f2);
1905 }
1906 }
1907 return FALSE;
1908}
1909
28bf4b0b 1910bool xllnoptgenerror (char *srcFile, int srcLine,
1911 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1912{
53306cab 1913 if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
616915dd 1914 {
1915 llsuppresshint ('+', o);
1916 flagcode_recordError (o);
1917 closeMessage ();
1918 return TRUE;
1919 }
1920
1921 flagcode_recordSuppressed (o);
1922 return FALSE;
1923}
1924
01a8227e 1925void xllparseerror (char *srcFile, int srcLine, cstring s)
616915dd 1926{
1927 if (context_getFlag (FLG_TRYTORECOVER))
1928 {
1929 parseerrorcount++;
1930
1931 if (parseerrorcount > GIVEUPPARSE)
1932 {
1933 if (cstring_isDefined (s))
1934 {
01a8227e 1935 xllfatalerror (srcFile, srcLine,
1936 message ("%q: Parse Error: %q. "
1937 "Too many errors, giving up.",
1938 fileloc_unparse (g_currentloc), s));
616915dd 1939 }
1940 else
1941 {
01a8227e 1942 xllfatalerror (srcFile, srcLine,
1943 message ("%q: Parse Error. Too many errors, giving up.",
1944 fileloc_unparse (g_currentloc)));
616915dd 1945 }
1946 }
1947 else
1948 {
1949 if (cstring_isDefined (s))
1950 {
1951 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1952 s));
01a8227e 1953 showSourceLoc (srcFile, srcLine);
616915dd 1954 }
1955 else
1956 {
1957 llreportparseerror (message ("Parse Error. Attempting to continue."));
01a8227e 1958 showSourceLoc (srcFile, srcLine);
616915dd 1959 }
1960 }
1961 }
1962 else
1963 {
1964 cstring msg;
1965
1966 if (cstring_isDefined (s))
1967 {
1968 msg = message ("Parse Error: %q.", s);
1969 }
1970 else
1971 {
1972 msg = message ("Parse Error.");
1973 }
1974
01a8227e 1975 xllfatalerror
1976 (srcFile, srcLine,
1977 message ("%q: %s (For help on parse errors, "
1b8ae690 1978 "see splint -help parseerrors.)",
616915dd 1979 fileloc_unparse (g_currentloc), msg));
1980 }
1981}
1982
28bf4b0b 1983bool xfsgenerror (char *srcFile, int srcLine,
53306cab 1984 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
28bf4b0b 1985{
1986 if (flagSpec_isOn (fs, fl))
1987 {
53306cab 1988 flagcode firston = flagSpec_getFirstOn (fs, fl);
1989
1990 if (llgenerroraux (firston, srcFile, srcLine, s,
1991 flagcodeHint (firston),
1992 fl, TRUE, FALSE))
28bf4b0b 1993 {
53306cab 1994 llsuppresshint ('-', firston);
1995 flagcode_recordError (firston);
28bf4b0b 1996 return TRUE;
1997 }
1998 else
1999 {
53306cab 2000 flagcode_recordSuppressed (firston);
28bf4b0b 2001 return FALSE;
2002 }
2003 }
2004 else
2005 {
2006 flagcode_recordSuppressed (flagSpec_getDominant (fs));
2007 cstring_free (s);
2008 return FALSE;
2009 }
2010}
2011
616915dd 2012bool doCheck (bool x, cstring pred, cstring file, int line)
2013{
2014 if (!x) {
2015 llbug (message ("%q: Check Failed: %s",
2016 fileloc_unparseRaw (file, line),
2017 pred));
2018 }
2019
2020 return x;
2021}
2022
2023/*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
2024{
2025 char *result;
2026
2027#ifndef VMS
2028#ifndef HAVE_STRERROR
2029 result = NULL;
2030#else
2031 result = strerror (errnum);
2032#endif
2033#else /* VMS */
2034 /* VAXCRTL's strerror() takes an optional second argument, which only
2035 matters when the first argument is EVMSERR. However, it's simplest
2036 just to pass it unconditionally. `vaxc$errno' is declared in
2037 <errno.h>, and maintained by the library in parallel with `errno'.
2038 We assume that caller's `errnum' either matches the last setting of
2039 `errno' by the library or else does not have the value `EVMSERR'. */
2040
2041 result = strerror (errnum, vaxc$errno);
2042#endif
2043
2044 if (result == NULL)
2045 {
2046 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
2047 }
2048
2049 return cstring_fromChars (result);
2050}
2051
2052void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
2053{
2054# if 0
2055# ifdef HOMEVERSION
2056 llflush ();
80489f0a 2057 printError (g_errorstream, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
2058 fileloc_unparse (g_currentloc),
2059 fileloc_unparseRaw (file, line),
2060 s, errno));
616915dd 2061 printCodePoint ();
2062 llflush ();
2063# endif
2064# else
2065 cstring_free (s);
2066# endif
2067}
2068
2069void llflush (void)
2070{
80489f0a 2071 (void) fflush (g_warningstream);
2072 (void) fflush (g_messagestream);
2073}
2074
80489f0a 2075void displayScan (cstring msg)
2076{
ce7034f0 2077 if (s_scanOpen)
2078 {
2079 displayScanClose ();
2080 }
2081
80489f0a 2082 llassert (!s_scanOpen);
2083
2084 if (context_getFlag (FLG_SHOWSCAN))
2085 {
ce7034f0 2086 showHerald ();
80489f0a 2087 fprintf (g_messagestream, "< %s >\n", cstring_toCharsSafe (msg));
2088 (void) fflush (g_messagestream);
2089 }
2090
2091 cstring_free (msg);
2092}
2093
2094void displayScanOpen (cstring msg)
2095{
ce7034f0 2096 if (s_scanOpen)
2097 {
2098 displayScanClose ();
2099 }
2100
80489f0a 2101 llassert (!s_scanOpen);
2102 s_scanOpen = TRUE;
2103
2104 if (context_getFlag (FLG_SHOWSCAN))
2105 {
2106 fprintf (g_messagestream, "< %s", cstring_toCharsSafe (msg));
2107 (void) fflush (g_messagestream);
2108 }
2109
2110 cstring_free (msg);
2111}
2112
2113void displayScanContinue (/*@temp@*/ cstring msg)
2114{
2115 if (context_getFlag (FLG_SHOWSCAN))
2116 {
6483a926 2117 if (s_scanOpen)
2118 {
2119 fprintf (g_messagestream, "%s", cstring_toCharsSafe (msg));
2120 (void) fflush (g_messagestream);
2121 }
2122 else
2123 {
2124 /*
2125 ** Don't call bug recursively
2126 */
2127
2128 fprintf (stderr, "*** Bug: scan continue scan not open\n");
2129 }
80489f0a 2130 }
2131}
2132
2133void displayScanClose (void)
2134{
6483a926 2135 if (s_scanOpen)
80489f0a 2136 {
6483a926 2137 if (context_getFlag (FLG_SHOWSCAN))
2138 {
2139 fprintf (g_messagestream, " >\n");
2140 (void) fflush (g_messagestream);
2141 }
80489f0a 2142 }
6483a926 2143 else
2144 {
2145 /*
2146 ** Don't call bug recursively
2147 */
2148
2149 fprintf (stderr, "*** Bug: scan close scan not open\n");
2150 }
2151
80489f0a 2152 s_scanOpen = FALSE;
616915dd 2153}
80489f0a 2154
2155
This page took 0.404345 seconds and 5 git commands to generate.