From a771a40e2257657cbdae0eb97a7bb8733db76b91 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 1 Jun 2010 11:20:18 -0700 Subject: [PATCH] Fix #if-skipping to *really* skip the skipped group. Previously we were avoiding printing within a skipped group, but we were still evluating directives such as #define and #undef and still emitting diagnostics for things such as macro calls with the wrong number of arguments. Add a test for this and fix it with a high-priority rule in the lexer that consumes the skipped content. --- glcpp-lex.l | 48 ++++++++++++++++++++++++---------- glcpp-parse.y | 15 +++-------- glcpp.h | 1 + tests/062-if-0-skips-garbage.c | 5 ++++ 4 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 tests/062-if-0-skips-garbage.c diff --git a/glcpp-lex.l b/glcpp-lex.l index 52269c6b306..a51d9e185fc 100644 --- a/glcpp-lex.l +++ b/glcpp-lex.l @@ -47,39 +47,58 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? %% -{HASH}define{HSPACE}+/{IDENTIFIER}"(" { +{HASH}if/.*\n { + yyextra->lexing_if = 1; yyextra->space_tokens = 0; - return HASH_DEFINE_FUNC; + return HASH_IF; } -{HASH}define { +{HASH}elif/.*\n { + yyextra->lexing_if = 1; yyextra->space_tokens = 0; - return HASH_DEFINE_OBJ; + return HASH_ELIF; } -{HASH}undef { +{HASH}else/.*\n { yyextra->space_tokens = 0; - return HASH_UNDEF; + return HASH_ELSE; } -{HASH}if { +{HASH}endif/.*\n { yyextra->space_tokens = 0; - return HASH_IF; + return HASH_ENDIF; } -{HASH}elif { + /* When skipping (due to an #if 0 or similar) consume anything + * up to a newline. We do this less priroty than any + * #if-related directive (#if, #elif, #else, #endif), but with + * more priority than any other directive or token to avoid + * any side-effects from skipped content. + * + * We use the lexing_if flag to avoid skipping any part of an + * if conditional expression. */ +[^\n]+/\n { + if (yyextra->lexing_if || + yyextra->skip_stack == NULL || + yyextra->skip_stack->type == SKIP_NO_SKIP) + { + REJECT; + } +} + +{HASH}define{HSPACE}+/{IDENTIFIER}"(" { yyextra->space_tokens = 0; - return HASH_ELIF; + return HASH_DEFINE_FUNC; } -{HASH}else { +{HASH}define { yyextra->space_tokens = 0; - return HASH_ELSE; + return HASH_DEFINE_OBJ; } -{HASH}endif { +{HASH}undef { yyextra->space_tokens = 0; - return HASH_ENDIF; + return HASH_UNDEF; } {HASH} { @@ -163,6 +182,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? } \n { + yyextra->lexing_if = 0; return NEWLINE; } diff --git a/glcpp-parse.y b/glcpp-parse.y index f4c834e038f..dd8e133f550 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -159,19 +159,11 @@ input: line: control_line { - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - printf ("\n"); - } + printf ("\n"); } | text_line { - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - _glcpp_parser_print_expanded_token_list (parser, $1); - printf ("\n"); - } + _glcpp_parser_print_expanded_token_list (parser, $1); + printf ("\n"); talloc_free ($1); } | expanded_line @@ -889,6 +881,7 @@ glcpp_parser_create (void) parser->defines = hash_table_ctor (32, hash_table_string_hash, hash_table_string_compare); parser->active = _string_list_create (parser); + parser->lexing_if = 0; parser->space_tokens = 1; parser->newline_as_space = 0; parser->in_control_line = 0; diff --git a/glcpp.h b/glcpp.h index 5c8c304a9ca..41fc2043d13 100644 --- a/glcpp.h +++ b/glcpp.h @@ -127,6 +127,7 @@ struct glcpp_parser { yyscan_t scanner; struct hash_table *defines; string_list_t *active; + int lexing_if; int space_tokens; int newline_as_space; int in_control_line; diff --git a/tests/062-if-0-skips-garbage.c b/tests/062-if-0-skips-garbage.c new file mode 100644 index 00000000000..d9e439bb890 --- /dev/null +++ b/tests/062-if-0-skips-garbage.c @@ -0,0 +1,5 @@ +#define foo(a,b) +#if 0 +foo(bar) +foo( +#endif -- 2.30.2