mirror of
https://github.com/cc65/cc65.git
synced 2024-06-01 13:41:34 +00:00
Merge pull request #2314 from acqn/PPFix
[cc65] Separated C preprocessor errors from other errors
This commit is contained in:
commit
4343eebe67
|
@ -59,8 +59,10 @@
|
||||||
|
|
||||||
|
|
||||||
/* Count of errors/warnings */
|
/* Count of errors/warnings */
|
||||||
unsigned ErrorCount = 0;
|
unsigned PPErrorCount = 0; /* Pre-parser errors */
|
||||||
unsigned WarningCount = 0;
|
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 RecentLineNo = 0;
|
||||||
unsigned RecentErrorCount = 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 */
|
/* Print an error message - internal function */
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s:%u: Error: ", Filename, LineNo);
|
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));
|
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
|
||||||
}
|
}
|
||||||
|
|
||||||
++ErrorCount;
|
if (EC != EC_PP) {
|
||||||
|
++ErrorCount;
|
||||||
|
} else {
|
||||||
|
++PPErrorCount;
|
||||||
|
}
|
||||||
if (RecentLineNo != LineNo) {
|
if (RecentLineNo != LineNo) {
|
||||||
RecentLineNo = LineNo;
|
RecentLineNo = LineNo;
|
||||||
RecentErrorCount = 0;
|
RecentErrorCount = 0;
|
||||||
|
@ -216,7 +222,7 @@ static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va
|
||||||
++RecentErrorCount;
|
++RecentErrorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RecentErrorCount > 20 || ErrorCount > 200) {
|
if (RecentErrorCount > 20 || GetTotalErrors () > 200) {
|
||||||
Fatal ("Too many errors");
|
Fatal ("Too many errors");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,18 +234,18 @@ void Error (const char* Format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
IntError (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
||||||
va_end (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 */
|
/* Print an error message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (GetInputName (LI), GetInputLine (LI), Format, ap);
|
IntError (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +256,7 @@ void PPError (const char* Format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
IntError (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
||||||
va_end (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 */
|
/* Print a warning message - internal function */
|
||||||
{
|
{
|
||||||
if (IS_Get (&WarningsAreErrors)) {
|
if (IS_Get (&WarningsAreErrors)) {
|
||||||
|
|
||||||
/* Treat the warning as an error */
|
/* Treat the warning as an error */
|
||||||
IntError (Filename, LineNo, Msg, ap);
|
IntError (EC, Filename, LineNo, Msg, ap);
|
||||||
|
|
||||||
} else if (IS_Get (&WarnEnable)) {
|
} else if (IS_Get (&WarnEnable)) {
|
||||||
|
|
||||||
|
@ -279,7 +285,12 @@ static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg,
|
||||||
if (Line) {
|
if (Line) {
|
||||||
Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (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_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
IntWarning (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap);
|
||||||
va_end (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 */
|
/* Print a warning message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (GetInputName (LI), GetInputLine (LI), Format, ap);
|
IntWarning (EC, GetInputName (LI), GetInputLine (LI), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +324,7 @@ void PPWarning (const char* Format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
IntWarning (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap);
|
||||||
va_end (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)
|
void ErrorReport (void)
|
||||||
/* Report errors (called at end of compile) */
|
/* Report errors (called at end of compile) */
|
||||||
{
|
{
|
||||||
unsigned int V = (ErrorCount != 0 ? 0 : 1);
|
unsigned TotalErrors = GetTotalErrors ();
|
||||||
Print (stdout, V, "%u errors and %u warnings generated.\n", ErrorCount, WarningCount);
|
unsigned TotalWarnings = GetTotalWarnings ();
|
||||||
|
unsigned int V = (TotalErrors != 0 ? 0 : 1);
|
||||||
|
Print (stdout, V, "%u errors and %u warnings generated.\n", TotalErrors, TotalWarnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
/* Count of errors/warnings */
|
||||||
extern unsigned ErrorCount;
|
extern unsigned PPErrorCount; /* Pre-parser errors */
|
||||||
extern unsigned WarningCount;
|
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 */
|
/* Warning and error options */
|
||||||
extern IntStack WarnEnable; /* Enable warnings */
|
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)));
|
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Print an error message */
|
/* 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 */
|
/* Print an error message with the line info given explicitly */
|
||||||
|
|
||||||
void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
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)));
|
void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Print a warning message */
|
/* 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 */
|
/* Print a warning message with the line info given explicitly */
|
||||||
|
|
||||||
void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
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)));
|
void PPNote (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Print a note message. For use within the preprocessor */
|
/* 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);
|
void ErrorReport (void);
|
||||||
/* Report errors (called at end of compile) */
|
/* Report errors (called at end of compile) */
|
||||||
|
|
||||||
|
|
|
@ -1089,7 +1089,7 @@ int main (int argc, char* argv[])
|
||||||
Compile (InputFile);
|
Compile (InputFile);
|
||||||
|
|
||||||
/* Create the output file if we didn't had any errors */
|
/* Create the output file if we didn't had any errors */
|
||||||
if (PreprocessOnly == 0 && (ErrorCount == 0 || Debug)) {
|
if (PreprocessOnly == 0 && (GetTotalErrors () == 0 || Debug)) {
|
||||||
|
|
||||||
/* Emit literals, do cleanup and optimizations */
|
/* Emit literals, do cleanup and optimizations */
|
||||||
FinishCompile ();
|
FinishCompile ();
|
||||||
|
@ -1115,5 +1115,5 @@ int main (int argc, char* argv[])
|
||||||
DoneSegAddrSizes ();
|
DoneSegAddrSizes ();
|
||||||
|
|
||||||
/* Return an apropriate exit code */
|
/* Return an apropriate exit code */
|
||||||
return (ErrorCount > 0)? EXIT_FAILURE : EXIT_SUCCESS;
|
return (GetTotalErrors () > 0)? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
8
test/err/bug2312-pperror-only.c
Normal file
8
test/err/bug2312-pperror-only.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/* Bug #2312 */
|
||||||
|
|
||||||
|
#error "Compiler should exit with failure"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -63,7 +63,8 @@ CUSTOMSOURCES = \
|
||||||
# exact error output is required
|
# exact error output is required
|
||||||
ERRORSOURCES = \
|
ERRORSOURCES = \
|
||||||
custom-reference-error.c \
|
custom-reference-error.c \
|
||||||
bug1889-missing-identifier.c
|
bug1889-missing-identifier.c \
|
||||||
|
bug2312-preprocessor-error.c
|
||||||
|
|
||||||
SOURCES := $(filter-out $(CUSTOMSOURCES) $(ERRORSOURCES),$(wildcard *.c))
|
SOURCES := $(filter-out $(CUSTOMSOURCES) $(ERRORSOURCES),$(wildcard *.c))
|
||||||
|
|
||||||
|
|
8
test/ref/bug2312-preprocessor-error.c
Normal file
8
test/ref/bug2312-preprocessor-error.c
Normal 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 */
|
2
test/ref/bug2312-preprocessor-error.cref
Normal file
2
test/ref/bug2312-preprocessor-error.cref
Normal 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
|
|
@ -13,7 +13,10 @@
|
||||||
and then "make" again to confirm
|
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 */
|
printf("%02x", 0x42); /* produce an error */
|
||||||
n = 0; /* produce an error */
|
n = 0; /* produce an error */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
custom-reference-error.c:18: Error: Call to undeclared function 'printf'
|
custom-reference-error.c:17: Error: #error
|
||||||
custom-reference-error.c:19: Error: Undeclared identifier 'n'
|
custom-reference-error.c:21: Error: Call to undeclared function 'printf'
|
||||||
custom-reference-error.c:21: Warning: Control reaches end of non-void function [-Wreturn-type]
|
custom-reference-error.c:22: Error: Undeclared identifier 'n'
|
||||||
custom-reference-error.c:21: Warning: Parameter 'argc' is never used
|
custom-reference-error.c:24: Warning: Control reaches end of non-void function [-Wreturn-type]
|
||||||
custom-reference-error.c:21: Warning: Parameter 'argv' is never used
|
custom-reference-error.c:24: Warning: Parameter 'argc' is never used
|
||||||
|
custom-reference-error.c:24: Warning: Parameter 'argv' is never used
|
||||||
|
|
Loading…
Reference in New Issue
Block a user