summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2000-04-08 04:00:02 +0000
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2000-04-08 04:00:02 +0000
commit852d1b04ed12dfb99ed1cb12c0415db592b74e5a (patch)
tree54f1e456f876159b92452e63265ec5cc24bf17b5
parent7771530ec44b7a3d6bc369d7bde2557f1efc14f7 (diff)
downloadgcc-852d1b04ed12dfb99ed1cb12c0415db592b74e5a.tar.gz
* 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
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/cpp.texi38
-rw-r--r--gcc/cppexp.c2
-rw-r--r--gcc/cppinit.c2
-rw-r--r--gcc/cpplex.c71
5 files changed, 107 insertions, 18 deletions
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 <NeilB@earthling.net>
+
+ * 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 <rth@cygnus.com>
* 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)