From: Carl Worth Date: Wed, 19 May 2010 14:29:22 +0000 (-0700) Subject: Fix bug (and add tests) for a function-like macro defined as itself. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=be0e2e9b2ada51be66afb6b44330acb44e0261f2;p=mesa.git Fix bug (and add tests) for a function-like macro defined as itself. This case worked previously, but broke in the recent rewrite of function- like macro expansion. The recursion was still terminated correctly, but any parenthesized expression after the macro name was still being swallowed even though the identifier was not being expanded as a macro. The fix is to notice earlier that the identifier is an already-expanding macro. We let the lexer know this through the classify_token function so that an already-expanding macro is lexed as an identifier, not a FUNC_MACRO. --- diff --git a/glcpp-parse.y b/glcpp-parse.y index 9f1075aa50a..8dc07483c18 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -427,6 +427,22 @@ glcpp_parser_destroy (glcpp_parser_t *parser) talloc_free (parser); } +static int +glcpp_parser_is_expanding (glcpp_parser_t *parser, const char *member) +{ + expansion_node_t *node; + + for (node = parser->expansions; node; node = node->next) { + if (node->macro && + strcmp (node->macro->identifier, member) == 0) + { + return 1; + } + } + + return 0; +} + token_class_t glcpp_parser_classify_token (glcpp_parser_t *parser, const char *identifier, @@ -457,6 +473,12 @@ glcpp_parser_classify_token (glcpp_parser_t *parser, if (macro == NULL) return TOKEN_CLASS_IDENTIFIER; + /* Don't consider this a macro if we are already actively + * expanding this macro. */ + if (glcpp_parser_is_expanding (parser, identifier)) + return TOKEN_CLASS_IDENTIFIER; + + /* Definitely a macro. Just need to check if it's function-like. */ if (macro->is_function) return TOKEN_CLASS_FUNC_MACRO; else @@ -580,37 +602,6 @@ glcpp_parser_pop_expansion (glcpp_parser_t *parser) talloc_free (node); } -int -glcpp_parser_is_expanding (glcpp_parser_t *parser, const char *member) -{ - expansion_node_t *node; - - for (node = parser->expansions; node; node = node->next) { - if (node->macro && - strcmp (node->macro->identifier, member) == 0) - { - return 1; - } - } - - return 0; -} - -static void -_expand_macro (glcpp_parser_t *parser, - const char *token, - macro_t *macro, - argument_list_t *arguments) -{ - /* Don't recurse if we're already actively expanding this token. */ - if (glcpp_parser_is_expanding (parser, token)) { - printf ("%s", token); - return; - } - - glcpp_parser_push_expansion_macro (parser, macro, arguments); -} - void _expand_object_macro (glcpp_parser_t *parser, const char *identifier) { @@ -618,8 +609,9 @@ _expand_object_macro (glcpp_parser_t *parser, const char *identifier) macro = hash_table_find (parser->defines, identifier); assert (! macro->is_function); + assert (! glcpp_parser_is_expanding (parser, identifier)); - _expand_macro (parser, identifier, macro, NULL); + glcpp_parser_push_expansion_macro (parser, macro, NULL); } void @@ -631,6 +623,7 @@ _expand_function_macro (glcpp_parser_t *parser, macro = hash_table_find (parser->defines, identifier); assert (macro->is_function); + assert (! glcpp_parser_is_expanding (parser, identifier)); if (_argument_list_length (arguments) != _string_list_length (macro->parameters)) @@ -643,5 +636,5 @@ _expand_function_macro (glcpp_parser_t *parser, return; } - _expand_macro (parser, identifier, macro, arguments); + glcpp_parser_push_expansion_macro (parser, macro, arguments); } diff --git a/tests/032-define-func-self-recurse.c b/tests/032-define-func-self-recurse.c new file mode 100644 index 00000000000..60d8526c0aa --- /dev/null +++ b/tests/032-define-func-self-recurse.c @@ -0,0 +1,2 @@ +#define foo(a) foo(2 * (a)) +foo(3) diff --git a/tests/033-define-func-self-compose.c b/tests/033-define-func-self-compose.c new file mode 100644 index 00000000000..8abaaf6be95 --- /dev/null +++ b/tests/033-define-func-self-compose.c @@ -0,0 +1,2 @@ +#define foo(a) foo(2 * (a)) +foo(foo(3))