Commit cef0d199 by Neil Booth Committed by Neil Booth

cpphash.h (struct_lexer_state): Delete was_skipping.

	* 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.

	* gcc.dg/cpp/extratokens.c: Fix.
	* gcc.dg/cpp/skipping2.c: New tests.

From-SVN: r44380
parent 2e824adb
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> 2001-07-26 Graham Stott <grahams@redhat.com>
* function.c (locate_and_pad_parm): Also pad initial offset * function.c (locate_and_pad_parm): Also pad initial offset
......
...@@ -126,6 +126,9 @@ struct lexer_state ...@@ -126,6 +126,9 @@ struct lexer_state
/* Nonzero if first token on line is CPP_HASH. */ /* Nonzero if first token on line is CPP_HASH. */
unsigned char in_directive; 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. */ /* Nonzero if in a directive that takes angle-bracketed headers. */
unsigned char angled_headers; unsigned char angled_headers;
...@@ -216,9 +219,6 @@ struct cpp_buffer ...@@ -216,9 +219,6 @@ struct cpp_buffer
buffers. */ buffers. */
unsigned char from_stage3; 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++. */ /* 1 = system header file, 2 = C system header file used for C++. */
unsigned char sysp; unsigned char sysp;
...@@ -342,9 +342,6 @@ struct cpp_reader ...@@ -342,9 +342,6 @@ struct cpp_reader
/* We're printed a warning recommending against using #import. */ /* We're printed a warning recommending against using #import. */
unsigned char import_warning; 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 /* Whether to print our version number. Done this way so
we don't get it twice for -v -version. */ we don't get it twice for -v -version. */
unsigned char print_version; unsigned char print_version;
......
...@@ -509,7 +509,7 @@ parse_identifier (pfile, c) ...@@ -509,7 +509,7 @@ parse_identifier (pfile, c)
/* $ is not a identifier character in the standard, but is commonly /* $ is not a identifier character in the standard, but is commonly
accepted as an extension. Don't warn about it in skipped accepted as an extension. Don't warn about it in skipped
conditional blocks. */ 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"); cpp_pedwarn (pfile, "'$' character(s) in identifier");
/* Identifiers are null-terminated. */ /* Identifiers are null-terminated. */
...@@ -521,7 +521,7 @@ parse_identifier (pfile, c) ...@@ -521,7 +521,7 @@ parse_identifier (pfile, c)
ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED); ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED);
/* Some identifiers require diagnostics when lexed. */ /* 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. */ /* It is allowed to poison the same identifier twice. */
if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok)
...@@ -888,7 +888,7 @@ _cpp_lex_token (pfile, result) ...@@ -888,7 +888,7 @@ _cpp_lex_token (pfile, result)
if (pfile->lexer_pos.col != 0 && !bol && !buffer->from_stage3) if (pfile->lexer_pos.col != 0 && !bol && !buffer->from_stage3)
cpp_pedwarn (pfile, "no newline at end of file"); cpp_pedwarn (pfile, "no newline at end of file");
pfile->state.next_bol = 1; pfile->state.next_bol = 1;
pfile->skipping = 0; /* In case missing #endif. */ pfile->state.skipping = 0; /* In case missing #endif. */
result->type = CPP_EOF; result->type = CPP_EOF;
/* Don't do MI optimisation. */ /* Don't do MI optimisation. */
return; return;
...@@ -915,7 +915,7 @@ _cpp_lex_token (pfile, result) ...@@ -915,7 +915,7 @@ _cpp_lex_token (pfile, result)
buffer->read_ahead = c; buffer->read_ahead = c;
pfile->state.next_bol = 1; pfile->state.next_bol = 1;
result->type = CPP_EOF; result->type = CPP_EOF;
/* Don't break; pfile->skipping might be true. */ /* Don't break; pfile->state.skipping might be true. */
return; return;
case '?': case '?':
...@@ -1261,7 +1261,7 @@ _cpp_lex_token (pfile, result) ...@@ -1261,7 +1261,7 @@ _cpp_lex_token (pfile, result)
break; break;
} }
if (pfile->skipping) if (!pfile->state.in_directive && pfile->state.skipping)
goto skip; goto skip;
/* If not in a directive, this token invalidates controlling macros. */ /* If not in a directive, this token invalidates controlling macros. */
......
...@@ -43,8 +43,9 @@ struct if_stack ...@@ -43,8 +43,9 @@ struct if_stack
struct if_stack *next; struct if_stack *next;
cpp_lexer_pos pos; /* line and column where condition started */ cpp_lexer_pos pos; /* line and column where condition started */
const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */ const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
unsigned char was_skipping; /* Value of pfile->skipping before this if. */ bool skip_elses; /* Can future #else / #elif be skipped? */
int type; /* type of last directive seen in this group */ 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 /* Values for the origin field of struct directive. KANDR directives
...@@ -220,8 +221,6 @@ static void ...@@ -220,8 +221,6 @@ static void
start_directive (pfile) start_directive (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
cpp_buffer *buffer = pfile->buffer;
/* Setup in-directive state. */ /* Setup in-directive state. */
pfile->state.in_directive = 1; pfile->state.in_directive = 1;
pfile->state.save_comments = 0; pfile->state.save_comments = 0;
...@@ -232,10 +231,6 @@ start_directive (pfile) ...@@ -232,10 +231,6 @@ start_directive (pfile)
/* Don't save directive tokens for external clients. */ /* Don't save directive tokens for external clients. */
pfile->la_saved = pfile->la_write; pfile->la_saved = pfile->la_write;
pfile->la_write = 0; 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. */ /* Called when leaving a directive, _Pragma or command-line directive. */
...@@ -244,12 +239,6 @@ end_directive (pfile, skip_line) ...@@ -244,12 +239,6 @@ end_directive (pfile, skip_line)
cpp_reader *pfile; cpp_reader *pfile;
int skip_line; 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 #. */ /* We don't skip for an assembler #. */
if (skip_line) if (skip_line)
skip_rest_of_line (pfile); skip_rest_of_line (pfile);
...@@ -270,7 +259,6 @@ _cpp_handle_directive (pfile, indented) ...@@ -270,7 +259,6 @@ _cpp_handle_directive (pfile, indented)
cpp_reader *pfile; cpp_reader *pfile;
int indented; int indented;
{ {
cpp_buffer *buffer = pfile->buffer;
const directive *dir = 0; const directive *dir = 0;
cpp_token dname; cpp_token dname;
int skip = 1; int skip = 1;
...@@ -293,7 +281,7 @@ _cpp_handle_directive (pfile, indented) ...@@ -293,7 +281,7 @@ _cpp_handle_directive (pfile, indented)
skipped conditional groups. Complain about this form if skipped conditional groups. Complain about this form if
we're being pedantic, but not if this is regurgitated input we're being pedantic, but not if this is regurgitated input
(preprocessed or fed back in by the C++ frontend). */ (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]; dir = &dtable[T_LINE];
pfile->state.line_extension = 1; pfile->state.line_extension = 1;
...@@ -361,7 +349,7 @@ _cpp_handle_directive (pfile, indented) ...@@ -361,7 +349,7 @@ _cpp_handle_directive (pfile, indented)
/* If we are skipping a failed conditional group, all /* If we are skipping a failed conditional group, all
non-conditional directives are ignored. */ non-conditional directives are ignored. */
if (! buffer->was_skipping || (dir->flags & COND)) if (! pfile->state.skipping || (dir->flags & COND))
{ {
/* Issue -pedantic warnings for extensions. */ /* Issue -pedantic warnings for extensions. */
if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION) if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION)
...@@ -376,7 +364,7 @@ _cpp_handle_directive (pfile, indented) ...@@ -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 /* An unknown directive. Don't complain about it in assembly
source: we don't know where the comments are, and # may source: we don't know where the comments are, and # may
...@@ -1256,7 +1244,7 @@ do_ifdef (pfile) ...@@ -1256,7 +1244,7 @@ do_ifdef (pfile)
{ {
int skip = 1; int skip = 1;
if (! pfile->buffer->was_skipping) if (! pfile->state.skipping)
{ {
const cpp_hashnode *node = lex_macro_node (pfile); const cpp_hashnode *node = lex_macro_node (pfile);
...@@ -1277,7 +1265,7 @@ do_ifndef (pfile) ...@@ -1277,7 +1265,7 @@ do_ifndef (pfile)
int skip = 1; int skip = 1;
const cpp_hashnode *node = 0; const cpp_hashnode *node = 0;
if (! pfile->buffer->was_skipping) if (! pfile->state.skipping)
{ {
node = lex_macro_node (pfile); node = lex_macro_node (pfile);
if (node) if (node)
...@@ -1302,7 +1290,7 @@ do_if (pfile) ...@@ -1302,7 +1290,7 @@ do_if (pfile)
int skip = 1; int skip = 1;
const cpp_hashnode *cmacro = 0; const cpp_hashnode *cmacro = 0;
if (! pfile->buffer->was_skipping) if (! pfile->state.skipping)
{ {
/* Controlling macro of #if ! defined () */ /* Controlling macro of #if ! defined () */
pfile->mi_ind_cmacro = 0; pfile->mi_ind_cmacro = 0;
...@@ -1336,16 +1324,17 @@ do_else (pfile) ...@@ -1336,16 +1324,17 @@ do_else (pfile)
} }
ifs->type = T_ELSE; ifs->type = T_ELSE;
/* Buffer->was_skipping is 1 if all conditionals in this chain /* Skip any future (erroneous) #elses or #elifs. */
have been false, 2 if a conditional has been true. */ pfile->state.skipping = ifs->skip_elses;
if (! ifs->was_skipping && buffer->was_skipping != 2) ifs->skip_elses = true;
buffer->was_skipping = ! buffer->was_skipping;
/* Invalidate any controlling macro. */ /* Invalidate any controlling macro. */
ifs->mi_cmacro = 0; 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 /* handle a #elif directive by not changing if_stack either. see the
...@@ -1370,23 +1359,23 @@ do_elif (pfile) ...@@ -1370,23 +1359,23 @@ do_elif (pfile)
} }
ifs->type = T_ELIF; ifs->type = T_ELIF;
/* Don't evaluate #elif if our higher level is skipping. */ /* Only evaluate this if we aren't skipping elses. During
if (! ifs->was_skipping) 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 pfile->state.skipping = 0;
chain have been false, 2 if a conditional has been true. */ pfile->state.skipping = ! _cpp_parse_expr (pfile);
if (buffer->was_skipping == 1) ifs->skip_elses = ! pfile->state.skipping;
buffer->was_skipping = ! _cpp_parse_expr (pfile);
else
buffer->was_skipping = 2;
/* Invalidate any controlling macro. */
ifs->mi_cmacro = 0;
} }
/* 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 static void
do_endif (pfile) do_endif (pfile)
...@@ -1399,6 +1388,10 @@ do_endif (pfile) ...@@ -1399,6 +1388,10 @@ do_endif (pfile)
cpp_error (pfile, "#endif without #if"); cpp_error (pfile, "#endif without #if");
else 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 potential control macro, we go back outside again. */
if (ifs->next == 0 && ifs->mi_cmacro) if (ifs->next == 0 && ifs->mi_cmacro)
{ {
...@@ -1407,14 +1400,12 @@ do_endif (pfile) ...@@ -1407,14 +1400,12 @@ do_endif (pfile)
} }
buffer->if_stack = ifs->next; buffer->if_stack = ifs->next;
buffer->was_skipping = ifs->was_skipping; pfile->state.skipping = ifs->was_skipping;
obstack_free (&pfile->buffer_ob, ifs); 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, If this is a #ifndef starting at the beginning of a file,
CMACRO is the macro name tested by the #ifndef. */ CMACRO is the macro name tested by the #ifndef. */
...@@ -1431,14 +1422,15 @@ push_conditional (pfile, skip, type, cmacro) ...@@ -1431,14 +1422,15 @@ push_conditional (pfile, skip, type, cmacro)
ifs = xobnew (&pfile->buffer_ob, struct if_stack); ifs = xobnew (&pfile->buffer_ob, struct if_stack);
ifs->pos = pfile->directive_pos; ifs->pos = pfile->directive_pos;
ifs->next = buffer->if_stack; 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; ifs->type = type;
if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0) if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0)
ifs->mi_cmacro = cmacro; ifs->mi_cmacro = cmacro;
else else
ifs->mi_cmacro = 0; ifs->mi_cmacro = 0;
buffer->was_skipping = skip; pfile->state.skipping = skip;
buffer->if_stack = ifs; buffer->if_stack = ifs;
} }
......
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> 2001-07-25 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* gcc.c-torture/execute/20010724-1.c: New file. * gcc.c-torture/execute/20010724-1.c: New file.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#ifndef foo bar /* { dg-error "extra tokens" "tokens after #ifndef" } */ #ifndef foo bar /* { dg-error "extra tokens" "tokens after #ifndef" } */
#endif #endif
#if 0 #if 1
#if 0 #if 0
#else foo /* { dg-warning "extra tokens" "tokens after #else" } */ #else foo /* { dg-warning "extra tokens" "tokens after #else" } */
#endif / /* { dg-warning "extra tokens" "tokens after #endif" } */ #endif / /* { dg-warning "extra tokens" "tokens after #endif" } */
......
/* 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" } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment