[PATCH 1/2] asm qualifiers (PR55681)
Segher Boessenkool
segher@kernel.crashing.org
Thu Nov 29 13:35:00 GMT 2018
+cc: C and C++ maintainers. Sorry I forgot before :-/
On Tue, Oct 30, 2018 at 05:30:33PM +0000, Segher Boessenkool wrote:
> PR55681 observes that currently only one qualifier is allowed for
> inline asm, so that e.g. "volatile asm" is allowed, "const asm" is also
> okay (with a warning), but "const volatile asm" gives an error. Also
> "const const asm" is an error (while "const const int" is okay for C),
> "goto" has to be last, and "_Atomic" isn't handled at all.
>
> This patch fixes all these. It allows any order of qualifiers (and
> goto), allows them all for C, allows duplications for C. For C++ it
> still allows only a single volatile and single goto, but in any order.
>
>
> 2018-10-30 Segher Boessenkool <segher@kernel.crashing.org>
>
> gcc/c/
> PR inline-asm/55681
> * c-parser.c (c_parser_for_statement): Update grammar. Allow any
> combination of type-qualifiers and goto in any order, with repetitions
> allowed.
>
> gcc/cp/
> PR inline-asm/55681
> * parser.c (cp_parser_using_directive): Update grammar. Allow any
> combination of volatile and goto in any order, without repetitions.
>
> ---
> gcc/c/c-parser.c | 66 +++++++++++++++++++++++++++---------------------
> gcc/cp/parser.c | 77 +++++++++++++++++++++++++++++++++++++-------------------
> 2 files changed, 89 insertions(+), 54 deletions(-)
>
> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
> index ee66ce8..ce9921e 100644
> --- a/gcc/c/c-parser.c
> +++ b/gcc/c/c-parser.c
> @@ -6283,23 +6283,31 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
> }
>
> /* Parse an asm statement, a GNU extension. This is a full-blown asm
> - statement with inputs, outputs, clobbers, and volatile tag
> + statement with inputs, outputs, clobbers, and volatile and goto tag
> allowed.
>
> + asm-qualifier:
> + type-qualifier
> + goto
> +
> + asm-qualifier-list:
> + asm-qualifier-list asm-qualifier
> + asm-qualifier
> +
> asm-statement:
> - asm type-qualifier[opt] ( asm-argument ) ;
> - asm type-qualifier[opt] goto ( asm-goto-argument ) ;
> + asm asm-qualifier-list[opt] ( asm-argument ) ;
>
> asm-argument:
> asm-string-literal
> asm-string-literal : asm-operands[opt]
> asm-string-literal : asm-operands[opt] : asm-operands[opt]
> - asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
> -
> - asm-goto-argument:
> + asm-string-literal : asm-operands[opt] : asm-operands[opt] \
> + : asm-clobbers[opt]
> asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
> : asm-goto-operands
>
> + The form with asm-goto-operands is valid if and only if the
> + asm-qualifier-list contains goto, and is the only allowed form in that case.
> Qualifiers other than volatile are accepted in the syntax but
> warned for. */
>
> @@ -6313,30 +6321,32 @@ c_parser_asm_statement (c_parser *parser)
>
> gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
> c_parser_consume_token (parser);
> - if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
> - {
> - quals = c_parser_peek_token (parser)->value;
> - c_parser_consume_token (parser);
> - }
> - else if (c_parser_next_token_is_keyword (parser, RID_CONST)
> - || c_parser_next_token_is_keyword (parser, RID_RESTRICT))
> - {
> - warning_at (c_parser_peek_token (parser)->location,
> - 0,
> - "%E qualifier ignored on asm",
> - c_parser_peek_token (parser)->value);
> - quals = NULL_TREE;
> - c_parser_consume_token (parser);
> - }
> - else
> - quals = NULL_TREE;
>
> + quals = NULL_TREE;
> is_goto = false;
> - if (c_parser_next_token_is_keyword (parser, RID_GOTO))
> - {
> - c_parser_consume_token (parser);
> - is_goto = true;
> - }
> + for (bool done = false; !done; )
> + switch (c_parser_peek_token (parser)->keyword)
> + {
> + case RID_VOLATILE:
> + quals = c_parser_peek_token (parser)->value;
> + c_parser_consume_token (parser);
> + break;
> + case RID_CONST:
> + case RID_RESTRICT:
> + case RID_ATOMIC:
> + warning_at (c_parser_peek_token (parser)->location,
> + 0,
> + "%E qualifier ignored on asm",
> + c_parser_peek_token (parser)->value);
> + c_parser_consume_token (parser);
> + break;
> + case RID_GOTO:
> + is_goto = true;
> + c_parser_consume_token (parser);
> + break;
> + default:
> + done = true;
> + }
>
> /* ??? Follow the C++ parser rather than using the
> lex_untranslated_string kludge. */
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index ebe326e..d44fd4d 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -19196,22 +19196,34 @@ cp_parser_using_directive (cp_parser* parser)
>
> /* Parse an asm-definition.
>
> + asm-qualifier:
> + volatile
> + goto
> +
> + asm-qualifier-list:
> + asm-qualifier
> + asm-qualifier-list asm-qualifier
> +
> asm-definition:
> asm ( string-literal ) ;
>
> GNU Extension:
>
> asm-definition:
> - asm volatile [opt] ( string-literal ) ;
> - asm volatile [opt] ( string-literal : asm-operand-list [opt] ) ;
> - asm volatile [opt] ( string-literal : asm-operand-list [opt]
> - : asm-operand-list [opt] ) ;
> - asm volatile [opt] ( string-literal : asm-operand-list [opt]
> - : asm-operand-list [opt]
> + asm asm-qualifier-list [opt] ( string-literal ) ;
> + asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt] ) ;
> + asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt]
> + : asm-operand-list [opt] ) ;
> + asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt]
> + : asm-operand-list [opt]
> : asm-clobber-list [opt] ) ;
> - asm volatile [opt] goto ( string-literal : : asm-operand-list [opt]
> - : asm-clobber-list [opt]
> - : asm-goto-list ) ; */
> + asm asm-qualifier-list [opt] ( string-literal : : asm-operand-list [opt]
> + : asm-clobber-list [opt]
> + : asm-goto-list ) ;
> +
> + The form with asm-goto-list is valid if and only if the asm-qualifier-list
> + contains goto, and is the only allowed form in that case. No duplicates are
> + allowed in an asm-qualifier-list. */
>
> static void
> cp_parser_asm_definition (cp_parser* parser)
> @@ -19240,23 +19252,36 @@ cp_parser_asm_definition (cp_parser* parser)
> }
>
> /* See if the next token is `volatile'. */
> - if (cp_parser_allow_gnu_extensions_p (parser)
> - && cp_lexer_next_token_is_keyword (parser->lexer, RID_VOLATILE))
> - {
> - /* Remember that we saw the `volatile' keyword. */
> - volatile_p = true;
> - /* Consume the token. */
> - cp_lexer_consume_token (parser->lexer);
> - }
> - if (cp_parser_allow_gnu_extensions_p (parser)
> - && parser->in_function_body
> - && cp_lexer_next_token_is_keyword (parser->lexer, RID_GOTO))
> - {
> - /* Remember that we saw the `goto' keyword. */
> - goto_p = true;
> - /* Consume the token. */
> - cp_lexer_consume_token (parser->lexer);
> - }
> + if (cp_parser_allow_gnu_extensions_p (parser))
> + for (bool done = false; !done ; )
> + switch (cp_lexer_peek_token (parser->lexer)->keyword)
> + {
> + case RID_VOLATILE:
> + if (!volatile_p)
> + {
> + /* Remember that we saw the `volatile' keyword. */
> + volatile_p = true;
> + /* Consume the token. */
> + cp_lexer_consume_token (parser->lexer);
> + }
> + else
> + done = true;
> + break;
> + case RID_GOTO:
> + if (!goto_p && parser->in_function_body)
> + {
> + /* Remember that we saw the `goto' keyword. */
> + goto_p = true;
> + /* Consume the token. */
> + cp_lexer_consume_token (parser->lexer);
> + }
> + else
> + done = true;
> + break;
> + default:
> + done = true;
> + }
> +
> /* Look for the opening `('. */
> if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
> return;
> --
> 1.8.3.1
More information about the Gcc-patches
mailing list