From: neil Date: Sat, 8 Apr 2000 04:00:02 +0000 (+0000) Subject: * cppexp.c (parse_charconst): Null does not end character X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;ds=sidebyside;h=852d1b04ed12dfb99ed1cb12c0415db592b74e5a;p=pf3gnuchains%2Fgcc-fork.git * cppexp.c (parse_charconst): Null does not end character constants. * cppinit.c (ISTABLE): Null character handled as whitespace. * cpplex.c (null_warning): new function. (skip_string): Emit warning if nulls encountered. (_cpp_skip_hspace): Emit warning if nulls encountered. (_cpp_lex_token): Emit warning if nulls encountered. Drop them. * cpp.texi: Update. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33013 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f99fa3c398e..c3c5b541503 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2000-04-08 Neil Booth + + * cppexp.c (parse_charconst): Null does not end character + constants. + * cppinit.c (ISTABLE): Null character handled as whitespace. + * cpplex.c (null_warning): new function. + (skip_string): Emit warning if nulls encountered. + (_cpp_skip_hspace): Emit warning if nulls encountered. + (_cpp_lex_token): Emit warning if nulls encountered. Drop + them. + * cpp.texi: Update. + 2000-04-07 Richard Henderson * flow.c (loop_depth): Remove. diff --git a/gcc/cpp.texi b/gcc/cpp.texi index 0d2b2ee335f..e0442a1c46c 100644 --- a/gcc/cpp.texi +++ b/gcc/cpp.texi @@ -138,6 +138,7 @@ and this may cause problems with other languages. @node Global Actions, Directives, Top, Top @section Transformations Made Globally +@cindex ASCII NUL handling Most C preprocessor features are inactive unless you give specific directives to request their use. (Preprocessing directives are lines starting with @@ -214,6 +215,43 @@ This exception is relevant only if you use the @samp{-trigraphs} option to enable trigraph processing. @xref{Invocation}. @end itemize +The preprocessor handles null characters embedded in the input file +depending upon the context in which the null appears. Note that here we +are referring not to the two-character escape sequence "\0", but to the +single character ASCII NUL. + +There are three different contexts in which a null character may +appear:- + +@itemize @bullet +@item +Within comments. Here, null characters are silently ignored. + +@item +Within a string or character constant. Here the preprocessor emits a +warning, but preserves the null character and passes it through to the +output file. + +@item +In any other context, the preprocessor issues a warning, and discards +the null character. In all other respects the preprocessor treats it +like whitespace, combining it with any surrounding whitespace to become +a single whitespace token. Representing the null character by "^@@", +this means that code like + +@example +#define X^@@1 +@end example + +is equivalent to + +@example +#define X 1 +@end example + +and X is defined with replacement text "1". +@end itemize + @node Directives, Header Files, Global Actions, Top @section Preprocessing Directives diff --git a/gcc/cppexp.c b/gcc/cppexp.c index 50a135110d1..31790999eef 100644 --- a/gcc/cppexp.c +++ b/gcc/cppexp.c @@ -274,7 +274,7 @@ parse_charconst (pfile, start, end) while (ptr < end) { c = *ptr++; - if (c == '\'' || c == '\0') + if (c == '\'') break; else if (c == '\\') { diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 62da1f34238..f4391ff006d 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -265,7 +265,7 @@ ISTABLE N('1') N('2') N('3') N('4') N('5') N('6') N('7') N('8') N('9') N('0') - H(' ') H('\t') H('\v') H('\f') + H('\0') H(' ') H('\t') H('\v') H('\f') S('\n') END diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 2e791200e45..b8a1b071161 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -45,6 +45,7 @@ static void skip_string PARAMS ((cpp_reader *, int)); static void parse_string PARAMS ((cpp_reader *, int)); static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *, unsigned long *)); static int null_cleanup PARAMS ((cpp_buffer *, cpp_reader *)); +static void null_warning PARAMS ((cpp_reader *, unsigned int)); /* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */ @@ -381,23 +382,38 @@ copy_comment (pfile, m) return ' '; } +static void +null_warning (pfile, count) + cpp_reader *pfile; + unsigned int count; +{ + if (count == 1) + cpp_warning (pfile, "embedded null character ignored"); + else + cpp_warning (pfile, "embedded null characters ignored"); +} + /* Skip whitespace \-newline and comments. Does not macro-expand. */ void _cpp_skip_hspace (pfile) cpp_reader *pfile; { + unsigned int null_count = 0; int c; + while (1) { c = GETC(); if (c == EOF) - return; + goto out; else if (is_hspace(c)) { if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile)) cpp_pedwarn (pfile, "%s in preprocessing directive", c == '\f' ? "formfeed" : "vertical tab"); + else if (c == '\0') + null_count++; } else if (c == '\r') { @@ -423,6 +439,9 @@ _cpp_skip_hspace (pfile) break; } FORWARD(-1); + out: + if (null_count) + null_warning (pfile, null_count); } /* Read and discard the rest of the current line. */ @@ -505,8 +524,9 @@ skip_string (pfile, c) int c; { long start_line, start_column; - cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column); + unsigned int null_count = 0; + cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column); while (1) { int cc = GETC(); @@ -521,8 +541,12 @@ skip_string (pfile, c) pfile->multiline_string_line, -1, "possible real start of unterminated constant"); pfile->multiline_string_line = 0; - return; + goto out; + case '\0': + null_count++; + break; + case '\n': CPP_BUMP_LINE (pfile); /* In Fortran and assembly language, silently terminate @@ -533,7 +557,7 @@ skip_string (pfile, c) || CPP_OPTION (pfile, lang_asm)) { FORWARD(-1); - return; + goto out; } /* Character constants may not extend over multiple lines. In Standard C, neither may strings. We accept multiline @@ -543,7 +567,7 @@ skip_string (pfile, c) cpp_error_with_line (pfile, start_line, start_column, "unterminated character constant"); FORWARD(-1); - return; + goto out; } if (CPP_PEDANTIC (pfile) && pfile->multiline_string_line == 0) cpp_pedwarn_with_line (pfile, start_line, start_column, @@ -570,10 +594,16 @@ skip_string (pfile, c) case '\"': case '\'': if (cc == c) - return; + goto out; break; } } + + out: + if (null_count == 1) + cpp_warning (pfile, "null character in string or character constant"); + else if (null_count > 1) + cpp_warning (pfile, "null characters in string or character constant"); } /* Parse a string and copy it to the output. */ @@ -976,16 +1006,25 @@ _cpp_lex_token (pfile) _cpp_parse_name (pfile, c); return CPP_MACRO; - case ' ': case '\t': case '\v': case '\f': - for (;;) - { - CPP_PUTC (pfile, c); - c = PEEKC (); - if (c == EOF || !is_hspace(c)) - break; - FORWARD(1); - } - return CPP_HSPACE; + case ' ': case '\t': case '\v': case '\f': case '\0': + { + int null_count = 0; + + for (;;) + { + if (c == '\0') + null_count++; + else + CPP_PUTC (pfile, c); + c = PEEKC (); + if (c == EOF || !is_hspace(c)) + break; + FORWARD(1); + } + if (null_count) + null_warning (pfile, null_count); + return CPP_HSPACE; + } case '\r': if (CPP_BUFFER (pfile)->has_escapes)