aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZack Weinberg <zack@wolery.cumb.org>2000-02-06 08:24:22 +0000
committerZack Weinberg <zack@gcc.gnu.org>2000-02-06 08:24:22 +0000
commiteaefae0ec35904e854d4f8a097fdb3e7c678aff8 (patch)
treeb4662b68daf63cc7cf16c2fab569a5dde8daa2ea /gcc
parent1316f1f7fcb21e1f5c807f2a3a84f177674e0e5b (diff)
downloadgcc-eaefae0ec35904e854d4f8a097fdb3e7c678aff8.zip
gcc-eaefae0ec35904e854d4f8a097fdb3e7c678aff8.tar.gz
gcc-eaefae0ec35904e854d4f8a097fdb3e7c678aff8.tar.bz2
cppfiles.c (read_and_prescan): Bump input pointer before possibly branching off to the backslash code.
* cppfiles.c (read_and_prescan) [case SPECCASE_QUESTION]: Bump input pointer before possibly branching off to the backslash code. * cpphash.c (macroexpand): Correctly delete \r escapes when stringifying parameters. * cpplib.c (copy_rest_of_line): Go directly to skip_block_comment if we can; bail out early if we hit a line comment. (handle_directive): Treat '# 123' in an .S file just like '# <punctuation>'. Discard the shifted '#' if we hit '#\n'. Return 1 for '# not_a_directive'. (get_directive_token): Pop macro buffers here, so that cpp_get_token can't sneakily move past a newline. Add sanity checks. (cpp_get_token): goto randomchar if handle_directive returns 0. From-SVN: r31819
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/cppfiles.c2
-rw-r--r--gcc/cpphash.c15
-rw-r--r--gcc/cpplib.c80
-rw-r--r--gcc/testsuite/gcc.dg/lineno-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/strpaste.c34
-rw-r--r--gcc/testsuite/gcc.dg/trigraphs.c28
7 files changed, 157 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a4e9b70..e0894f9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
2000-02-05 Zack Weinberg <zack@wolery.cumb.org>
+ * cppfiles.c (read_and_prescan) [case SPECCASE_QUESTION]: Bump
+ input pointer before possibly branching off to the backslash
+ code.
+ * cpphash.c (macroexpand): Correctly delete \r escapes when
+ stringifying parameters.
+ * cpplib.c (copy_rest_of_line): Go directly to skip_block_comment
+ if we can; bail out early if we hit a line comment.
+ (handle_directive): Treat '# 123' in an .S file just like
+ '# <punctuation>'. Discard the shifted '#' if we hit '#\n'.
+ Return 1 for '# not_a_directive'.
+ (get_directive_token): Pop macro buffers here, so that
+ cpp_get_token can't sneakily move past a newline.
+ Add sanity checks.
+ (cpp_get_token): goto randomchar if handle_directive returns 0.
+
* cppalloc.c: Update copyright.
* cpplib.c: Merge all the static function prototypes into one
block.
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index a89a0ca..36e3305 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -1017,6 +1017,7 @@ read_and_prescan (pfile, fp, desc, len)
*op++ = '?';
break;
}
+ ip += 2;
if (CPP_OPTIONS (pfile)->warn_trigraphs)
{
unsigned long col;
@@ -1042,7 +1043,6 @@ read_and_prescan (pfile, fp, desc, len)
*op++ = '?';
*op++ = d;
}
- ip += 2;
}
}
}
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
index c2244c9..64491c5 100644
--- a/gcc/cpphash.c
+++ b/gcc/cpphash.c
@@ -1158,18 +1158,17 @@ macroexpand (pfile, hp)
if (!in_string)
{
+ /* Delete "\r " and "\r-" escapes. */
+ if (c == '\r')
+ {
+ i++;
+ continue;
+ }
/* Internal sequences of whitespace are
replaced by one space except within
a string or char token. */
- if (is_space(c))
+ else if (is_space(c))
{
- if (CPP_WRITTEN (pfile) > (unsigned) arg->stringified
- && (CPP_PWRITTEN (pfile))[-1] == '\r')
- {
- /* "\r " escape markers are removed */
- CPP_ADJUST_WRITTEN (pfile, -1);
- continue;
- }
if (need_space == 0)
need_space = 1;
continue;
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 409eb08..40c3c3a 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -468,15 +468,18 @@ copy_rest_of_line (pfile)
parse_string (pfile, c);
continue;
case '/':
- if (PEEKC() == '*' && CPP_TRADITIONAL (pfile))
+ if (PEEKC() == '*')
{
- CPP_PUTS (pfile, "/**/", 4);
- skip_comment (pfile, c);
+ if (CPP_TRADITIONAL (pfile))
+ CPP_PUTS (pfile, "/**/", 4);
+ skip_block_comment (pfile);
continue;
}
/* else fall through */
case '-':
c = skip_comment (pfile, c);
+ if (c == ' ')
+ return;
break;
case '\f':
@@ -527,10 +530,7 @@ handle_directive (pfile)
if (c >= '0' && c <= '9')
{
if (CPP_OPTIONS (pfile)->lang_asm)
- {
- skip_rest_of_line (pfile);
- return 1;
- }
+ return 0;
if (CPP_PEDANTIC (pfile)
&& ! CPP_PREPROCESSED (pfile)
@@ -552,21 +552,20 @@ handle_directive (pfile)
ident_length = CPP_PWRITTEN (pfile) - ident;
if (ident_length == 0)
{
- /* A line of just `#' becomes blank. */
- if (PEEKC() == '\n')
- return 1;
- else
- return 0;
+ /* A line of just `#' becomes blank. A line with something
+ other than an identifier after the # is reparsed as a non-
+ directive line. */
+ CPP_SET_WRITTEN (pfile, old_written);
+ return (PEEKC() == '\n');
}
- /*
- * Decode the keyword and call the appropriate expansion
- * routine, after moving the input pointer up to the next line.
- */
+ /* Decode the keyword and call the appropriate expansion routine. */
for (kt = directive_table; ; kt++)
{
if (kt->length <= 0)
- return 0;
+ /* # identifier, but not a legit directive. Pass onward as a
+ CPP_DIRECTIVE token anyway - let the consumer worry about it. */
+ return 1;
if (kt->length == ident_length
&& !strncmp (kt->name, ident, ident_length))
break;
@@ -983,26 +982,43 @@ static enum cpp_token
get_directive_token (pfile)
cpp_reader *pfile;
{
+ long old_written = CPP_WRITTEN (pfile);
+ enum cpp_token token;
+
for (;;)
{
- long old_written = CPP_WRITTEN (pfile);
- enum cpp_token token;
cpp_skip_hspace (pfile);
if (PEEKC () == '\n')
- return CPP_VSPACE;
+ return CPP_VSPACE;
+
token = cpp_get_token (pfile);
- switch (token)
- {
- case CPP_POP:
- if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
- return token;
- /* ... else fall though ... */
- case CPP_HSPACE: case CPP_COMMENT:
+ /* token could be hspace at the beginning of a macro. */
+ if (token == CPP_HSPACE || token == CPP_COMMENT)
+ {
CPP_SET_WRITTEN (pfile, old_written);
- break;
- default:
+ continue;
+ }
+
+ /* token cannot be vspace, it would have been caught above. */
+ if (token == CPP_VSPACE)
+ {
+ cpp_fatal (pfile, "VSPACE in get_directive_token");
return token;
- }
+ }
+
+ /* token cannot be POP unless the buffer is a macro buffer. */
+ if (token != CPP_POP)
+ return token;
+
+ if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+ {
+ cpp_fatal (pfile, "POP of file buffer in get_directive_token");
+ return token;
+ }
+
+ /* We must pop the buffer by hand, else cpp_get_token might hand
+ us whitespace or newline on the next invocation. */
+ cpp_pop_buffer (pfile);
}
}
@@ -2246,7 +2262,7 @@ if_directive_name (pfile, ifs)
/* Get the next token, and add it to the text in pfile->token_buffer.
Return the kind of token we got. */
-
+
enum cpp_token
cpp_get_token (pfile)
cpp_reader *pfile;
@@ -2345,7 +2361,7 @@ cpp_get_token (pfile)
if (handle_directive (pfile))
return CPP_DIRECTIVE;
pfile->only_seen_white = 0;
- return CPP_OTHER;
+ goto randomchar;
case '\"':
case '\'':
diff --git a/gcc/testsuite/gcc.dg/lineno-2.c b/gcc/testsuite/gcc.dg/lineno-2.c
new file mode 100644
index 0000000..64647e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lineno-2.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+/* Test #line with and without macros for the line number. */
+
+#define L 90
+
+#line 44
+int i = __LINE__;
+
+#line L
+int j = __LINE__;
+
+#line 14 /* N.B. the _next_ line is line 14. */
+
+int main(void)
+{
+ if (i != 44)
+ abort ();
+ if (j != 90)
+ abort ();
+ if (__LINE__ != 21)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/strpaste.c b/gcc/testsuite/gcc.dg/strpaste.c
new file mode 100644
index 0000000..56e1484
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strpaste.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+
+/* Regression test for stringizing and token pasting.
+ We got internal escape markers in the strings. */
+
+#include <string.h>
+
+#define S(x) _S(x)
+#define _S(x) #x
+
+#define I 1
+static const char s1[] = S(I.1);
+static const char t1[] = "1.1";
+
+#define f h
+#define h(a) a+f
+static const char s2[] = S( f(1)(2) );
+static const char t2[] = "1+h(2)";
+
+#undef I
+#undef f
+#undef h
+
+int
+main(void)
+{
+ if (strcmp (s1, t1))
+ abort ();
+
+ if (strcmp (s2, t2))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/trigraphs.c b/gcc/testsuite/gcc.dg/trigraphs.c
new file mode 100644
index 0000000..62ac103
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/trigraphs.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-ansi" } */
+
+/* Basic tests for trigraph conversion.
+ All of them are here, but not in all possible contexts. *??/
+/
+
+??=include <stdio.h>
+
+??=define TWELVE 1??/
+2
+
+static const char str??(??) = "0123456789??/n";
+
+int
+main(void)
+??<
+ if (sizeof str != TWELVE)
+ abort ();
+
+ if ((5 ??' 3) != 6)
+ abort ();
+
+ if ((5 ??! 3) != 7)
+ abort ();
+
+ return 0;
+??>