cpplib: Fix PR 1011. Tighten up #line flags.
Neil Booth
neil@daikokuya.demon.co.uk
Sat Dec 9 03:53:00 GMT 2000
Fixed PR 1011, and only restricts the flags on #NUMBER lines to the
valid possibilities. Test cases for both.
Neil.
* cppfiles.c (NEVER_REREAD, DO_NOT_REREAD): Move from cpphash.h.
* cpphash.h (NEVER_REREAD, DO_NOT_REREAD, ABSOLUTE_PATH): Delete.
* cpplex.c (parse_identifier): Improve diagnostic.
(_cpp_lex_token): Return unconditionally at the end of a directive.
* cpplib.c (read_flag): Verify legality of each flag.
(end_directive): Resotre pfile->skipping before skip_rest_of_line.
(do_line): Use the new read_flag.
* cppmacro.c (struct cpp_macro, parse_arg, replace_args,
check_macro_redefinition, parse_params): Rename var_args to
variadic.
* gcc.dg/cpp/lineflags.c: New tests.
* gcc.dg/cpp/poison.c: Update.
* gcc.dg/cpp/redef2.c: Update.
* gcc.dg/cpp/skipping.c: New test.
Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.90
diff -u -p -r1.90 cppfiles.c
--- cppfiles.c 2000/12/07 23:17:56 1.90
+++ cppfiles.c 2000/12/09 11:34:54
@@ -80,6 +80,16 @@ struct include_file
unsigned char defined; /* cmacro prevents inclusion in this state */
};
+/* The cmacro works like this: If it's NULL, the file is to be
+ included again. If it's NEVER_REREAD, the file is never to be
+ included again. Otherwise it is a macro hashnode, and the file is
+ to be included again if the macro is defined or not as specified by
+ DEFINED. */
+#define NEVER_REREAD ((const cpp_hashnode *)-1)
+#define DO_NOT_REREAD(inc) \
+((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
+ || ((inc)->cmacro->type == NT_MACRO) == (inc)->defined))
+
static struct file_name_map *read_name_map
PARAMS ((cpp_reader *, const char *));
static char *read_filename_string PARAMS ((int, FILE *));
Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.86
diff -u -p -r1.86 cpphash.h
--- cpphash.h 2000/12/08 03:00:23 1.86
+++ cpphash.h 2000/12/09 11:35:00
@@ -68,18 +68,7 @@ struct file_name_list
Only used on MS-DOS and related platforms. */
struct file_name_map *name_map;
};
-#define ABSOLUTE_PATH ((struct file_name_list *)-1)
-/* The cmacro works like this: If it's NULL, the file is to be
- included again. If it's NEVER_REREAD, the file is never to be
- included again. Otherwise it is a macro hashnode, and the file is
- to be included again if the macro is defined or not as specified by
- DEFINED. */
-#define NEVER_REREAD ((const cpp_hashnode *)-1)
-#define DO_NOT_REREAD(inc) \
-((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
- || ((inc)->cmacro->type == NT_MACRO) == (inc)->defined))
-
struct cpp_buffer
{
const unsigned char *cur; /* current position */
@@ -168,10 +157,8 @@ extern unsigned char _cpp_trigraph_map[U
#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
#define CPP_IN_SYSTEM_HEADER(PFILE) \
(CPP_BUFFER (PFILE) && CPP_BUFFER (PFILE)->sysp)
-#define CPP_PEDANTIC(PF) \
- CPP_OPTION (PF, pedantic)
-#define CPP_WTRADITIONAL(PF) \
- CPP_OPTION (PF, warn_traditional)
+#define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic)
+#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
/* Hash step. The hash calculation is duplicated in cpp_lookup and
parse_name. */
Index: cpplex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplex.c,v
retrieving revision 1.123
diff -u -p -r1.123 cpplex.c
--- cpplex.c 2000/12/06 20:12:59 1.123
+++ cpplex.c 2000/12/09 11:35:07
@@ -521,10 +521,10 @@ parse_identifier (pfile, c)
cpp_error (pfile, "attempt to use poisoned \"%s\"", result->name);
/* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the
- replacement list of a variable-arguments macro. */
+ replacement list of a variadic macro. */
if (result == pfile->spec_nodes.n__VA_ARGS__
&& !pfile->state.va_args_ok)
- cpp_pedwarn (pfile, "__VA_ARGS__ can only appear in the expansion of a C99 variable-argument macro");
+ cpp_pedwarn (pfile, "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro");
}
return result;
@@ -907,7 +907,8 @@ _cpp_lex_token (pfile, result)
buffer->read_ahead = c;
pfile->state.next_bol = 1;
result->type = CPP_EOF;
- break;
+ /* Don't break; pfile->skipping might be true. */
+ return;
case '?':
case '\\':
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.229
diff -u -p -r1.229 cpplib.c
--- cpplib.c 2000/12/07 23:17:55 1.229
+++ cpplib.c 2000/12/09 11:35:07
@@ -90,7 +90,7 @@ static int glue_header_name PARAMS ((cpp
static int parse_include PARAMS ((cpp_reader *, cpp_token *));
static void push_conditional PARAMS ((cpp_reader *, int, int,
const cpp_hashnode *));
-static unsigned int read_flag PARAMS ((cpp_reader *));
+static unsigned int read_flag PARAMS ((cpp_reader *, unsigned int));
static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
unsigned long *));
static void do_diagnostic PARAMS ((cpp_reader *, enum error_type, int));
@@ -247,14 +247,14 @@ end_directive (pfile, skip_line)
{
cpp_buffer *buffer = pfile->buffer;
+ /* Restore pfile->skipping before skip_rest_of_line, so that e.g.
+ __VA_ARGS__ in the rest of the directive doesn't warn. */
+ pfile->skipping = buffer->was_skipping;
+
/* We don't skip for an assembler #. */
if (skip_line)
skip_rest_of_line (pfile);
- /* Restore pfile->skipping after skip_rest_of_line. Otherwise the
- lexer might not return! */
- pfile->skipping = buffer->was_skipping;
-
/* Restore state. */
pfile->la_write = pfile->la_saved;
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
@@ -639,22 +639,26 @@ do_include_next (pfile)
_cpp_execute_include (pfile, &header, 0, 1);
}
-/* Subroutine of do_line. Read possible flags after file name. If it
- is a number between 1 and 4, return it, otherwise return 0. If
- it's not the end of the directive complain. */
+/* Subroutine of do_line. Read possible flags after file name. LAST
+ is the last flag seen; 0 if this is the first flag. Return the flag
+ if it is valid, 0 at the end of the directive. Otherwise complain. */
static unsigned int
-read_flag (pfile)
+read_flag (pfile, last)
cpp_reader *pfile;
+ unsigned int last;
{
cpp_token token;
_cpp_lex_token (pfile, &token);
if (token.type == CPP_NUMBER && token.val.str.len == 1)
{
- unsigned int flag = token.val.str.text[0] - '1';
- if (flag <= 3)
- return flag + 1;
+ unsigned int flag = token.val.str.text[0] - '0';
+
+ if (flag > last && flag <= 4
+ && (flag != 4 || last == 3)
+ && (flag != 2 || last == 0))
+ return flag;
}
if (token.type != CPP_EOF)
@@ -733,31 +737,33 @@ do_line (pfile)
_cpp_simplify_pathname (fname);
buffer->nominal_fname = fname;
- if (pfile->state.line_extension)
+ if (! pfile->state.line_extension)
+ check_eol (pfile);
+ else
{
- int flag, sysp = 0;
+ int flag = 0, sysp = 0;
- flag = read_flag (pfile);
+ flag = read_flag (pfile, flag);
if (flag == 1)
{
reason = FC_ENTER;
- flag = read_flag (pfile);
+ flag = read_flag (pfile, flag);
}
else if (flag == 2)
{
reason = FC_LEAVE;
- flag = read_flag (pfile);
+ flag = read_flag (pfile, flag);
}
if (flag == 3)
{
- flag = read_flag (pfile);
sysp = 1;
+ flag = read_flag (pfile, flag);
+ if (flag == 4)
+ sysp = 2, read_flag (pfile, flag);
}
- cpp_make_system_header (pfile, sysp, flag == 4);
+ cpp_make_system_header (pfile, sysp, sysp == 2);
}
-
- check_eol (pfile);
}
else if (token.type != CPP_EOF)
{
Index: cppmacro.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmacro.c,v
retrieving revision 1.34
diff -u -p -r1.34 cppmacro.c
--- cppmacro.c 2000/12/03 12:06:23 1.34
+++ cppmacro.c 2000/12/09 11:35:11
@@ -42,7 +42,7 @@ struct cpp_macro
unsigned int count; /* Number of tokens in expansion. */
unsigned short paramc; /* Number of parameters. */
unsigned int fun_like : 1; /* If a function-like macro. */
- unsigned int var_args : 1; /* If a variable-args macro. */
+ unsigned int variadic : 1; /* If a variadic macro. */
unsigned int disabled : 1; /* If macro is disabled. */
};
@@ -475,13 +475,13 @@ paste_all_tokens (pfile, lhs)
}
/* Reads the unexpanded tokens of a macro argument into ARG. VAR_ARGS
- is non-zero if this is a variable argument. Returns the type of
- the token that caused reading to finish. */
+ is non-zero if this is a variadic macro. Returns the type of the
+ token that caused reading to finish. */
static enum cpp_ttype
-parse_arg (pfile, arg, var_args)
+parse_arg (pfile, arg, variadic)
cpp_reader *pfile;
struct macro_arg *arg;
- int var_args;
+ int variadic;
{
enum cpp_ttype result;
unsigned int paren = 0;
@@ -509,8 +509,8 @@ parse_arg (pfile, arg, var_args)
paren++;
else if (result == CPP_CLOSE_PAREN && paren-- == 0)
break;
- /* Commas are not terminators within parantheses or var_args. */
- else if (result == CPP_COMMA && paren == 0 && !var_args)
+ /* Commas are not terminators within parantheses or variadic. */
+ else if (result == CPP_COMMA && paren == 0 && !variadic)
break;
else if (result == CPP_EOF)
break; /* Error reported by caller. */
@@ -541,7 +541,7 @@ parse_args (pfile, node)
{
argc++;
- type = parse_arg (pfile, cur, argc == macro->paramc && macro->var_args);
+ type = parse_arg (pfile, cur, argc == macro->paramc && macro->variadic);
if (type == CPP_CLOSE_PAREN || type == CPP_EOF)
break;
@@ -566,7 +566,7 @@ parse_args (pfile, node)
This is exactly the same as if there had been an empty rest
argument - debug("string", ). */
- if (argc + 1 == macro->paramc && macro->var_args)
+ if (argc + 1 == macro->paramc && macro->variadic)
{
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "ISO C99 requires rest arguments to be used");
@@ -794,7 +794,7 @@ replace_args (pfile, macro, args, list)
given no actual arguments (not merely if b is an
empty argument); otherwise pasting is turned off. */
if (dest[-1].type == CPP_COMMA
- && macro->var_args
+ && macro->variadic
&& src->val.arg_no == macro->paramc)
{
if (count == 0)
@@ -1182,7 +1182,7 @@ check_macro_redefinition (pfile, node, m
if (macro1->count != macro2->count
|| macro1->paramc != macro2->paramc
|| macro1->fun_like != macro2->fun_like
- || macro1->var_args != macro2->var_args)
+ || macro1->variadic != macro2->variadic)
return 0;
/* Check each token. */
@@ -1287,18 +1287,17 @@ parse_params (pfile, macro)
continue;
case CPP_ELLIPSIS:
- macro->var_args = 1;
+ macro->variadic = 1;
if (!prev_ident)
{
save_parameter (pfile, macro, pfile->spec_nodes.n__VA_ARGS__);
pfile->state.va_args_ok = 1;
if (! CPP_OPTION (pfile, c99) && CPP_OPTION (pfile, pedantic))
cpp_pedwarn (pfile,
- "anonymous variable arguments were introduced in C99");
+ "anonymous variadic macros were introduced in C99");
}
else if (CPP_OPTION (pfile, pedantic))
- cpp_pedwarn (pfile,
- "ISO C does not permit named variable arguments");
+ cpp_pedwarn (pfile, "ISO C does not permit named variadic macros");
/* We're at the end, and just expect a closing parenthesis. */
_cpp_lex_token (pfile, &token);
@@ -1368,7 +1367,7 @@ _cpp_create_definition (pfile, node)
macro->params = 0;
macro->paramc = 0;
macro->fun_like = 0;
- macro->var_args = 0;
+ macro->variadic = 0;
macro->count = 0;
macro->expansion = (cpp_token *) POOL_FRONT (&pfile->macro_pool);
@@ -1598,7 +1597,7 @@ cpp_macro_definition (pfile, node)
if (i + 1 < macro->paramc)
*buffer++ = ',', *buffer++ = ' ';
- else if (macro->var_args)
+ else if (macro->variadic)
*buffer++ = '.', *buffer++ = '.', *buffer++ = '.';
}
*buffer++ = ')';
Index: testsuite/gcc.dg/cpp/lineflags.c
===================================================================
RCS file: lineflags.c
diff -N lineflags.c
--- /dev/null Tue May 5 13:32:27 1998
+++ lineflags.c Sat Dec 9 03:35:26 2000
@@ -0,0 +1,35 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc. */
+
+/* { dg-do preprocess } */
+/* { dg-options "-fno-show-column" } */
+
+/* This tests whether various combinations of flags are correctly
+ accepted after #line.
+
+ Neil Booth, 8 Dec 2000. */
+
+#line 12 "file" 3 /* { dg-warning "extra tokens" } */
+
+# 14 "file" 1 1 /* { dg-error "invalid flag" } */
+# 15 "file" 1 2 /* { dg-error "invalid flag" } */
+# 16 "file" 1 3 3 /* { dg-error "invalid flag" } */
+# 17 "file" 1 4 /* { dg-error "invalid flag" } */
+# 18 "file" 2 3 4 4 /* { dg-error "invalid flag" } */
+# 19 "file" 2 4 /* { dg-error "invalid flag" } */
+# 20 "file" 2 2 /* { dg-error "invalid flag" } */
+# 21 "file" 2 1 /* { dg-error "invalid flag" } */
+# 22 "file" 4 /* { dg-error "invalid flag" } */
+# 23 "file" 4 5 /* { dg-error "invalid flag" } */
+# 24 "file" 0 /* { dg-error "invalid flag" } */
+# 25 "file" 5 /* { dg-error "invalid flag" } */
+# 26 "file" foo /* { dg-error "invalid flag" } */
+
+
+# 29 "file" 1 /* { dg-bogus "invalid flag" } */
+# 30 "file" 2 /* { dg-bogus "invalid flag" } */
+# 31 "file" 1 3 /* { dg-bogus "invalid flag" } */
+# 32 "file" 2 3 /* { dg-bogus "invalid flag" } */
+# 33 "file" 1 3 4 /* { dg-bogus "invalid flag" } */
+# 34 "file" 2 3 4 /* { dg-bogus "invalid flag" } */
+# 35 "file" 3 /* { dg-bogus "invalid flag" } */
+# 36 "file" 3 4 /* { dg-bogus "invalid flag" } */
Index: testsuite/gcc.dg/cpp/poison.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/cpp/poison.c,v
retrieving revision 1.2
diff -u -p -r1.2 poison.c
--- poison.c 2000/12/01 22:03:57 1.2
+++ poison.c 2000/12/09 11:35:26
@@ -15,10 +15,10 @@ foo5 /* { dg-error "foo5" "use of foo5
#define foo6 345 /* { dg-error "foo6" "def of foo6" } */
#define foo6 456 /* { dg-error "foo6" "redef of foo6" } */
#ifdef foo6 /* { dg-error "foo6" "#ifdef foo6" } */
-#error hey! foo6 poisoned! /* { dg-error "foo6" "poisoned identifiers" } */
+#error hey! foo6 defined!
#endif
#if defined(foo6) /* { dg-error "foo6" "#if defined foo6" } */
-#error foo6 still poisoned! /* { dg-error "foo6" "poisoned identifiers" } */
+#error foo6 still defined!
#else
foo6 /* { dg-error "foo6" "use of foo6" } */
#endif
Index: testsuite/gcc.dg/cpp/redef2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/cpp/redef2.c,v
retrieving revision 1.2
diff -u -p -r1.2 redef2.c
--- redef2.c 2000/10/28 18:01:40 1.2
+++ redef2.c 2000/12/09 11:35:26
@@ -26,5 +26,5 @@
{ dg-warning "previous" "prev def ro" { target *-*-* } 11 }
{ dg-warning "previous" "prev def va" { target *-*-* } 14 }
- { dg-warning "named variable" "named" { target *-*-* } 14 }
- { dg-warning "anonymous variable" "anon" { target *-*-* } 15 } */
+ { dg-warning "named var" "named variadic" { target *-*-* } 14 }
+ { dg-warning "anonymous var" "anon variadic" { target *-*-* } 15 } */
Index: testsuite/gcc.dg/cpp/skipping.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/cpp/skipping.c,v
retrieving revision 1.1
diff -u -p -r1.1 skipping.c
--- skipping.c 2000/10/29 17:43:57 1.1
+++ skipping.c 2000/12/09 11:35:26
@@ -18,3 +18,8 @@ F( /* No diagnostic: don't even try to
#else
#error Macros not expanded in #elif
#endif
+
+/* Check we don't warn about bad identifiers when skipping. */
+#if 0
+#define foo __VA_ARGS__ /* { dg-bogus "warned about identifier" } */
+#endif
More information about the Gcc-patches
mailing list