Separated C preprocessor errors from other errors.

This commit is contained in:
acqn 2023-12-18 15:30:53 +08:00
parent 05aae60816
commit cd7c688dff
7 changed files with 91 additions and 30 deletions

View File

@ -59,8 +59,10 @@
/* Count of errors/warnings */
unsigned ErrorCount = 0;
unsigned WarningCount = 0;
unsigned PPErrorCount = 0; /* Pre-parser errors */
unsigned PPWarningCount = 0; /* Pre-parser warnings */
unsigned ErrorCount = 0; /* Errors occurred in parser and later translation phases */
unsigned WarningCount = 0; /* Warnings occurred in parser and later translation phases */
unsigned RecentLineNo = 0;
unsigned RecentErrorCount = 0;
@ -197,7 +199,7 @@ void Internal (const char* Format, ...)
static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
static void IntError (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print an error message - internal function */
{
fprintf (stderr, "%s:%u: Error: ", Filename, LineNo);
@ -208,7 +210,11 @@ static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
}
++ErrorCount;
if (EC != EC_PP) {
++ErrorCount;
} else {
++PPErrorCount;
}
if (RecentLineNo != LineNo) {
RecentLineNo = LineNo;
RecentErrorCount = 0;
@ -216,7 +222,7 @@ static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va
++RecentErrorCount;
}
if (RecentErrorCount > 20 || ErrorCount > 200) {
if (RecentErrorCount > 20 || GetTotalErrors () > 200) {
Fatal ("Too many errors");
}
}
@ -228,18 +234,18 @@ void Error (const char* Format, ...)
{
va_list ap;
va_start (ap, Format);
IntError (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
IntError (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
va_end (ap);
}
void LIError (const LineInfo* LI, const char* Format, ...)
void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...)
/* Print an error message with the line info given explicitly */
{
va_list ap;
va_start (ap, Format);
IntError (GetInputName (LI), GetInputLine (LI), Format, ap);
IntError (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
va_end (ap);
}
@ -250,7 +256,7 @@ void PPError (const char* Format, ...)
{
va_list ap;
va_start (ap, Format);
IntError (GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
IntError (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
va_end (ap);
}
@ -262,13 +268,13 @@ void PPError (const char* Format, ...)
static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
static void IntWarning (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
/* Print a warning message - internal function */
{
if (IS_Get (&WarningsAreErrors)) {
/* Treat the warning as an error */
IntError (Filename, LineNo, Msg, ap);
IntError (EC, Filename, LineNo, Msg, ap);
} else if (IS_Get (&WarnEnable)) {
@ -279,7 +285,12 @@ static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg,
if (Line) {
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
}
++WarningCount;
if (EC != EC_PP) {
++WarningCount;
} else {
++PPWarningCount;
}
}
}
@ -291,18 +302,18 @@ void Warning (const char* Format, ...)
{
va_list ap;
va_start (ap, Format);
IntWarning (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
IntWarning (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
va_end (ap);
}
void LIWarning (const LineInfo* LI, const char* Format, ...)
void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...)
/* Print a warning message with the line info given explicitly */
{
va_list ap;
va_start (ap, Format);
IntWarning (GetInputName (LI), GetInputLine (LI), Format, ap);
IntWarning (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
va_end (ap);
}
@ -313,7 +324,7 @@ void PPWarning (const char* Format, ...)
{
va_list ap;
va_start (ap, Format);
IntWarning (GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
IntWarning (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
va_end (ap);
}
@ -398,16 +409,34 @@ void PPNote (const char* Format, ...)
/*****************************************************************************/
/* Code */
/* Error summary */
/*****************************************************************************/
unsigned GetTotalErrors (void)
/* Get total count of errors of all categories */
{
return PPErrorCount + ErrorCount;
}
unsigned GetTotalWarnings (void)
/* Get total count of warnings of all categories */
{
return PPWarningCount + WarningCount;
}
void ErrorReport (void)
/* Report errors (called at end of compile) */
{
unsigned int V = (ErrorCount != 0 ? 0 : 1);
Print (stdout, V, "%u errors and %u warnings generated.\n", ErrorCount, WarningCount);
unsigned TotalErrors = GetTotalErrors ();
unsigned TotalWarnings = GetTotalWarnings ();
unsigned int V = (TotalErrors != 0 ? 0 : 1);
Print (stdout, V, "%u errors and %u warnings generated.\n", TotalErrors, TotalWarnings);
}

View File

@ -55,9 +55,20 @@
/* Error categories */
typedef enum errcat_t errcat_t;
enum errcat_t {
EC_PP, /* Pre-parser phases */
EC_PARSER, /* Parser and later phases */
};
/* Count of errors/warnings */
extern unsigned ErrorCount;
extern unsigned WarningCount;
extern unsigned PPErrorCount; /* Pre-parser errors */
extern unsigned PPWarningCount; /* Pre-parser warnings */
extern unsigned ErrorCount; /* Errors occurred in parser and later translation phases */
extern unsigned WarningCount; /* Warnings occurred in parser and later translation phases */
/* Warning and error options */
extern IntStack WarnEnable; /* Enable warnings */
@ -98,7 +109,7 @@ void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1,
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print an error message */
void LIError (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3)));
void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
/* Print an error message with the line info given explicitly */
void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
@ -107,7 +118,7 @@ void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print a warning message */
void LIWarning (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3)));
void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
/* Print a warning message with the line info given explicitly */
void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
@ -130,6 +141,12 @@ void LINote (const LineInfo* LI, const char* Format, ...) attribute ((format (pr
void PPNote (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print a note message. For use within the preprocessor */
unsigned GetTotalErrors (void);
/* Get total count of errors of all categories */
unsigned GetTotalWarnings (void);
/* Get total count of warnings of all categories */
void ErrorReport (void);
/* Report errors (called at end of compile) */

View File

@ -63,7 +63,8 @@ CUSTOMSOURCES = \
# exact error output is required
ERRORSOURCES = \
custom-reference-error.c \
bug1889-missing-identifier.c
bug1889-missing-identifier.c \
bug2312-preprocessor-error.c
SOURCES := $(filter-out $(CUSTOMSOURCES) $(ERRORSOURCES),$(wildcard *.c))

View File

@ -0,0 +1,8 @@
/* Bug #2312 - Error recovery from preprocessor errors at the end of a declaration */
typedef int A; /* ';' consumption triggers PP below */
#define /* PP error during ';' consumption */
A f(void); /* Should be OK */
int A(void); /* Should be an error */

View File

@ -0,0 +1,2 @@
bug2312-preprocessor-error.c:5: Error: Missing macro name
bug2312-preprocessor-error.c:8: Error: Redefinition of typedef 'A' as different kind of symbol

View File

@ -13,7 +13,10 @@
and then "make" again to confirm
*/
short main(int argc, char* argv[])
typedef short return_t;
#error /* produce an error */
return_t main(int argc, char* argv[])
{
printf("%02x", 0x42); /* produce an error */
n = 0; /* produce an error */

View File

@ -1,5 +1,6 @@
custom-reference-error.c:18: Error: Call to undeclared function 'printf'
custom-reference-error.c:19: Error: Undeclared identifier 'n'
custom-reference-error.c:21: Warning: Control reaches end of non-void function [-Wreturn-type]
custom-reference-error.c:21: Warning: Parameter 'argc' is never used
custom-reference-error.c:21: Warning: Parameter 'argv' is never used
custom-reference-error.c:17: Error: #error
custom-reference-error.c:21: Error: Call to undeclared function 'printf'
custom-reference-error.c:22: Error: Undeclared identifier 'n'
custom-reference-error.c:24: Warning: Control reaches end of non-void function [-Wreturn-type]
custom-reference-error.c:24: Warning: Parameter 'argc' is never used
custom-reference-error.c:24: Warning: Parameter 'argv' is never used