From 5d6342ebc23344e8168b1589589b68f7b6781f66 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 21 May 2008 21:52:57 +0000 Subject: [PATCH] re PR preprocessor/27777 (Bad diagnostic emission when #error contains a trigraph) gcc/testsuite PR preprocessor/27777: * gcc.dg/cpp/pr27777.c: New file. libcpp PR preprocessor/27777: * lex.c (cpp_output_line_to_string): New function. * internal.h (_cpp_begin_message): Don't declare. * errors.c (_cpp_begin_message): Now static. * include/cpplib.h (cpp_output_line_to_string): Declare. * directives.c (do_diagnostic): Rewrote. Use cpp_output_line_to_string. Don't use _cpp_begin_message. From-SVN: r135740 --- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/cpp/pr27777.c | 8 +++++ libcpp/ChangeLog | 10 +++++++ libcpp/directives.c | 22 +++++++++----- libcpp/errors.c | 2 +- libcpp/include/cpplib.h | 2 ++ libcpp/internal.h | 4 --- libcpp/lex.c | 47 +++++++++++++++++++++++++++++- 8 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/pr27777.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 11f44b99e7e..3a88c77c1a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-05-21 Tom Tromey + + PR preprocessor/27777: + * gcc.dg/cpp/pr27777.c: New file. + 2008-05-21 Jakub Jelinek PR c++/36023 diff --git a/gcc/testsuite/gcc.dg/cpp/pr27777.c b/gcc/testsuite/gcc.dg/cpp/pr27777.c new file mode 100644 index 00000000000..89258b95e9f --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr27777.c @@ -0,0 +1,8 @@ +/* PR preprocessor/27777 */ +/* { dg-do preprocess } */ +/* { dg-options { -trigraphs -Wall } } */ + +#error "BUG??!" + +/* { dg-error "BUG" "" { target *-*-* } 5 } */ +/* { dg-warning "trigraph" "" { target *-*-* } 5 } */ diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 58632e3f548..7f31ff4e79a 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,13 @@ +2008-05-21 Tom Tromey + + PR preprocessor/27777: + * lex.c (cpp_output_line_to_string): New function. + * internal.h (_cpp_begin_message): Don't declare. + * errors.c (_cpp_begin_message): Now static. + * include/cpplib.h (cpp_output_line_to_string): Declare. + * directives.c (do_diagnostic): Rewrote. Use + cpp_output_line_to_string. Don't use _cpp_begin_message. + 2008-05-21 Tom Tromey * include/symtab.h (HT_ALLOCED): Remove. diff --git a/libcpp/directives.c b/libcpp/directives.c index 9954796b36a..8e7778d12e2 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -1016,14 +1016,20 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, static void do_diagnostic (cpp_reader *pfile, int code, int print_dir) { - if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0)) - { - if (print_dir) - fprintf (stderr, "#%s ", pfile->directive->name); - pfile->state.prevent_expansion++; - cpp_output_line (pfile, stderr); - pfile->state.prevent_expansion--; - } + const unsigned char *dir_name; + unsigned char *line; + source_location src_loc = pfile->cur_token[-1].src_loc; + + if (print_dir) + dir_name = pfile->directive->name; + else + dir_name = NULL; + pfile->state.prevent_expansion++; + line = cpp_output_line_to_string (pfile, dir_name); + pfile->state.prevent_expansion--; + + cpp_error_with_line (pfile, code, src_loc, 0, "%s", line); + free (line); } static void diff --git a/libcpp/errors.c b/libcpp/errors.c index 0b7c1e0f458..5e8e637276d 100644 --- a/libcpp/errors.c +++ b/libcpp/errors.c @@ -76,7 +76,7 @@ print_location (cpp_reader *pfile, source_location line, unsigned int col) big enough max_column_hint.) Returns 0 if the error has been suppressed. */ -int +static int _cpp_begin_message (cpp_reader *pfile, int code, source_location src_loc, unsigned int column) { diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 6b3f7615c57..76288a9068c 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -844,6 +844,8 @@ extern void cpp_error_with_line (cpp_reader *, int, source_location, unsigned, /* In lex.c */ extern int cpp_ideq (const cpp_token *, const char *); extern void cpp_output_line (cpp_reader *, FILE *); +extern unsigned char *cpp_output_line_to_string (cpp_reader *, + const unsigned char *); extern void cpp_output_token (const cpp_token *, FILE *); extern const char *cpp_type2name (enum cpp_ttype); /* Returns the value of an escape sequence, truncated to the correct diff --git a/libcpp/internal.h b/libcpp/internal.h index 860fe2e53a2..187b31140f3 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -518,10 +518,6 @@ cpp_in_primary_file (cpp_reader *pfile) return pfile->line_table->depth == 1; } -/* In errors.c */ -extern int _cpp_begin_message (cpp_reader *, int, - source_location, unsigned int); - /* In macro.c */ extern void _cpp_free_definition (cpp_hashnode *); extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *); diff --git a/libcpp/lex.c b/libcpp/lex.c index 772a8701654..70897fd57db 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -1,5 +1,5 @@ /* CPP Library - lexical analysis. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. Contributed by Per Bothner, 1994-95. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -1539,6 +1539,51 @@ cpp_output_line (cpp_reader *pfile, FILE *fp) putc ('\n', fp); } +/* Return a string representation of all the remaining tokens on the + current line. The result is allocated using xmalloc and must be + freed by the caller. */ +unsigned char * +cpp_output_line_to_string (cpp_reader *pfile, const unsigned char *dir_name) +{ + const cpp_token *token; + unsigned int out = dir_name ? ustrlen (dir_name) : 0; + unsigned int alloced = 120 + out; + unsigned char *result = (unsigned char *) xmalloc (alloced); + + /* If DIR_NAME is empty, there are no initial contents. */ + if (dir_name) + { + sprintf ((char *) result, "#%s ", dir_name); + out += 2; + } + + token = cpp_get_token (pfile); + while (token->type != CPP_EOF) + { + unsigned char *last; + /* Include room for a possible space and the terminating nul. */ + unsigned int len = cpp_token_len (token) + 2; + + if (out + len > alloced) + { + alloced *= 2; + if (out + len > alloced) + alloced = out + len; + result = (unsigned char *) xrealloc (result, alloced); + } + + last = cpp_spell_token (pfile, token, &result[out], 0); + out = last - result; + + token = cpp_get_token (pfile); + if (token->flags & PREV_WHITE) + result[out++] = ' '; + } + + result[out] = '\0'; + return result; +} + /* Memory buffers. Changing these three constants can have a dramatic effect on performance. The values here are reasonable defaults, but might be tuned. If you adjust them, be sure to test across a -- 2.30.2