diff options
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cpphash.h | 9 | ||||
-rw-r--r-- | gcc/cpplex.c | 10 | ||||
-rw-r--r-- | gcc/cpplib.c | 82 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/extratokens.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/skipping2.c | 14 |
7 files changed, 79 insertions, 57 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 39e6022..35835ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2001-07-26 Neil Booth <neil@cat.daikokuya.demon.co.uk> + + * cpphash.h (struct_lexer_state): Delete was_skipping. + Move skipping here from struct cpp_reader. + * cpplex.c (parse_identifier): Update. + (_cpp_lex_token): Don't skip tokens in a directive. + * cpplib.c (struct if_stack): Update. + (start_directive, end_directive): Don't change skipping state. + (_cpp_handle_directive): Update. + (do_ifdef, do_ifndef, do_if, do_elif): Similarly. + (do_else, do_endif): Update; only check for excess tokens if not + in a skipped conditional block. + (push_conditional): Update for new struct if_stack. + 2001-07-26 Graham Stott <grahams@redhat.com> * function.c (locate_and_pad_parm): Also pad initial offset diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 56d9068..a8221d9 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -126,6 +126,9 @@ struct lexer_state /* Nonzero if first token on line is CPP_HASH. */ unsigned char in_directive; + /* True if we are skipping a failed conditional group. */ + unsigned char skipping; + /* Nonzero if in a directive that takes angle-bracketed headers. */ unsigned char angled_headers; @@ -216,9 +219,6 @@ struct cpp_buffer buffers. */ unsigned char from_stage3; - /* Temporary storage for pfile->skipping whilst in a directive. */ - unsigned char was_skipping; - /* 1 = system header file, 2 = C system header file used for C++. */ unsigned char sysp; @@ -342,9 +342,6 @@ struct cpp_reader /* We're printed a warning recommending against using #import. */ unsigned char import_warning; - /* True if we are skipping a failed conditional group. */ - unsigned char skipping; - /* Whether to print our version number. Done this way so we don't get it twice for -v -version. */ unsigned char print_version; diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 7424827..4821745 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -509,7 +509,7 @@ parse_identifier (pfile, c) /* $ is not a identifier character in the standard, but is commonly accepted as an extension. Don't warn about it in skipped conditional blocks. */ - if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->skipping) + if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->state.skipping) cpp_pedwarn (pfile, "'$' character(s) in identifier"); /* Identifiers are null-terminated. */ @@ -521,7 +521,7 @@ parse_identifier (pfile, c) ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED); /* Some identifiers require diagnostics when lexed. */ - if (result->flags & NODE_DIAGNOSTIC && !pfile->skipping) + if (result->flags & NODE_DIAGNOSTIC && !pfile->state.skipping) { /* It is allowed to poison the same identifier twice. */ if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) @@ -888,7 +888,7 @@ _cpp_lex_token (pfile, result) if (pfile->lexer_pos.col != 0 && !bol && !buffer->from_stage3) cpp_pedwarn (pfile, "no newline at end of file"); pfile->state.next_bol = 1; - pfile->skipping = 0; /* In case missing #endif. */ + pfile->state.skipping = 0; /* In case missing #endif. */ result->type = CPP_EOF; /* Don't do MI optimisation. */ return; @@ -915,7 +915,7 @@ _cpp_lex_token (pfile, result) buffer->read_ahead = c; pfile->state.next_bol = 1; result->type = CPP_EOF; - /* Don't break; pfile->skipping might be true. */ + /* Don't break; pfile->state.skipping might be true. */ return; case '?': @@ -1261,7 +1261,7 @@ _cpp_lex_token (pfile, result) break; } - if (pfile->skipping) + if (!pfile->state.in_directive && pfile->state.skipping) goto skip; /* If not in a directive, this token invalidates controlling macros. */ diff --git a/gcc/cpplib.c b/gcc/cpplib.c index e0f6124..c196c1f 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -43,8 +43,9 @@ struct if_stack struct if_stack *next; cpp_lexer_pos pos; /* line and column where condition started */ const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */ - unsigned char was_skipping; /* Value of pfile->skipping before this if. */ - int type; /* type of last directive seen in this group */ + bool skip_elses; /* Can future #else / #elif be skipped? */ + bool was_skipping; /* If were skipping on entry. */ + int type; /* Most recent conditional, for diagnostics. */ }; /* Values for the origin field of struct directive. KANDR directives @@ -220,8 +221,6 @@ static void start_directive (pfile) cpp_reader *pfile; { - cpp_buffer *buffer = pfile->buffer; - /* Setup in-directive state. */ pfile->state.in_directive = 1; pfile->state.save_comments = 0; @@ -232,10 +231,6 @@ start_directive (pfile) /* Don't save directive tokens for external clients. */ pfile->la_saved = pfile->la_write; pfile->la_write = 0; - - /* Turn off skipping. */ - buffer->was_skipping = pfile->skipping; - pfile->skipping = 0; } /* Called when leaving a directive, _Pragma or command-line directive. */ @@ -244,12 +239,6 @@ end_directive (pfile, skip_line) cpp_reader *pfile; int 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); @@ -270,7 +259,6 @@ _cpp_handle_directive (pfile, indented) cpp_reader *pfile; int indented; { - cpp_buffer *buffer = pfile->buffer; const directive *dir = 0; cpp_token dname; int skip = 1; @@ -293,7 +281,7 @@ _cpp_handle_directive (pfile, indented) skipped conditional groups. Complain about this form if we're being pedantic, but not if this is regurgitated input (preprocessed or fed back in by the C++ frontend). */ - if (! buffer->was_skipping && CPP_OPTION (pfile, lang) != CLK_ASM) + if (! pfile->state.skipping && CPP_OPTION (pfile, lang) != CLK_ASM) { dir = &dtable[T_LINE]; pfile->state.line_extension = 1; @@ -361,7 +349,7 @@ _cpp_handle_directive (pfile, indented) /* If we are skipping a failed conditional group, all non-conditional directives are ignored. */ - if (! buffer->was_skipping || (dir->flags & COND)) + if (! pfile->state.skipping || (dir->flags & COND)) { /* Issue -pedantic warnings for extensions. */ if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION) @@ -376,7 +364,7 @@ _cpp_handle_directive (pfile, indented) } } } - else if (dname.type != CPP_EOF && ! buffer->was_skipping) + else if (dname.type != CPP_EOF && ! pfile->state.skipping) { /* An unknown directive. Don't complain about it in assembly source: we don't know where the comments are, and # may @@ -1256,7 +1244,7 @@ do_ifdef (pfile) { int skip = 1; - if (! pfile->buffer->was_skipping) + if (! pfile->state.skipping) { const cpp_hashnode *node = lex_macro_node (pfile); @@ -1277,7 +1265,7 @@ do_ifndef (pfile) int skip = 1; const cpp_hashnode *node = 0; - if (! pfile->buffer->was_skipping) + if (! pfile->state.skipping) { node = lex_macro_node (pfile); if (node) @@ -1302,7 +1290,7 @@ do_if (pfile) int skip = 1; const cpp_hashnode *cmacro = 0; - if (! pfile->buffer->was_skipping) + if (! pfile->state.skipping) { /* Controlling macro of #if ! defined () */ pfile->mi_ind_cmacro = 0; @@ -1336,16 +1324,17 @@ do_else (pfile) } ifs->type = T_ELSE; - /* Buffer->was_skipping is 1 if all conditionals in this chain - have been false, 2 if a conditional has been true. */ - if (! ifs->was_skipping && buffer->was_skipping != 2) - buffer->was_skipping = ! buffer->was_skipping; + /* Skip any future (erroneous) #elses or #elifs. */ + pfile->state.skipping = ifs->skip_elses; + ifs->skip_elses = true; /* Invalidate any controlling macro. */ ifs->mi_cmacro = 0; - } - check_eol (pfile); + /* Only check EOL if was not originally skipping. */ + if (!ifs->was_skipping) + check_eol (pfile); + } } /* handle a #elif directive by not changing if_stack either. see the @@ -1370,23 +1359,23 @@ do_elif (pfile) } ifs->type = T_ELIF; - /* Don't evaluate #elif if our higher level is skipping. */ - if (! ifs->was_skipping) + /* Only evaluate this if we aren't skipping elses. During + evaluation, set skipping to false to get lexer warnings. */ + if (ifs->skip_elses) + pfile->state.skipping = 1; + else { - /* Buffer->was_skipping is 1 if all conditionals in this - chain have been false, 2 if a conditional has been true. */ - if (buffer->was_skipping == 1) - buffer->was_skipping = ! _cpp_parse_expr (pfile); - else - buffer->was_skipping = 2; - - /* Invalidate any controlling macro. */ - ifs->mi_cmacro = 0; + pfile->state.skipping = 0; + pfile->state.skipping = ! _cpp_parse_expr (pfile); + ifs->skip_elses = ! pfile->state.skipping; } + + /* Invalidate any controlling macro. */ + ifs->mi_cmacro = 0; } } -/* #endif pops the if stack and resets pfile->skipping. */ +/* #endif pops the if stack and resets pfile->state.skipping. */ static void do_endif (pfile) @@ -1399,6 +1388,10 @@ do_endif (pfile) cpp_error (pfile, "#endif without #if"); else { + /* Only check EOL if was not originally skipping. */ + if (!ifs->was_skipping) + check_eol (pfile); + /* If potential control macro, we go back outside again. */ if (ifs->next == 0 && ifs->mi_cmacro) { @@ -1407,14 +1400,12 @@ do_endif (pfile) } buffer->if_stack = ifs->next; - buffer->was_skipping = ifs->was_skipping; + pfile->state.skipping = ifs->was_skipping; obstack_free (&pfile->buffer_ob, ifs); } - - check_eol (pfile); } -/* Push an if_stack entry and set pfile->skipping accordingly. +/* Push an if_stack entry and set pfile->state.skipping accordingly. If this is a #ifndef starting at the beginning of a file, CMACRO is the macro name tested by the #ifndef. */ @@ -1431,14 +1422,15 @@ push_conditional (pfile, skip, type, cmacro) ifs = xobnew (&pfile->buffer_ob, struct if_stack); ifs->pos = pfile->directive_pos; ifs->next = buffer->if_stack; - ifs->was_skipping = buffer->was_skipping; + ifs->skip_elses = pfile->state.skipping || !skip; + ifs->was_skipping = pfile->state.skipping; ifs->type = type; if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0) ifs->mi_cmacro = cmacro; else ifs->mi_cmacro = 0; - buffer->was_skipping = skip; + pfile->state.skipping = skip; buffer->if_stack = ifs; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5a6aea2..805bbb5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2001-07-26 Neil Booth <neil@cat.daikokuya.demon.co.uk> + + * gcc.dg/cpp/extratokens.c: Fix. + * gcc.dg/cpp/skipping2.c: New tests. + 2001-07-25 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> * gcc.c-torture/execute/20010724-1.c: New file. diff --git a/gcc/testsuite/gcc.dg/cpp/extratokens.c b/gcc/testsuite/gcc.dg/cpp/extratokens.c index 0941be7..c06a41d 100644 --- a/gcc/testsuite/gcc.dg/cpp/extratokens.c +++ b/gcc/testsuite/gcc.dg/cpp/extratokens.c @@ -15,7 +15,7 @@ #ifndef foo bar /* { dg-error "extra tokens" "tokens after #ifndef" } */ #endif -#if 0 +#if 1 #if 0 #else foo /* { dg-warning "extra tokens" "tokens after #else" } */ #endif / /* { dg-warning "extra tokens" "tokens after #endif" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/skipping2.c b/gcc/testsuite/gcc.dg/cpp/skipping2.c new file mode 100644 index 0000000..3b0d0f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/skipping2.c @@ -0,0 +1,14 @@ +/* Copyright (C) 2001 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ + +/* Tests that excess tokens in skipped conditional blocks don't warn. */ + +/* Source: Neil Booth, 25 Jul 2001. */ + +#if 0 +#if foo +#else foo /* { dg-bogus "extra tokens" "extra tokens in skipped block" } */ +#endif foo /* { dg-bogus "extra tokens" "extra tokens in skipped block" } */ +#endif bar /* { dg-warning "extra tokens" "tokens after #endif" } */ + |