From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5913 invoked by alias); 30 Oct 2018 17:31:16 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 119481 invoked by uid 89); 30 Oct 2018 17:30:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.5 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy= X-HELO: gcc1-power7.osuosl.org Received: from gcc1-power7.osuosl.org (HELO gcc1-power7.osuosl.org) (140.211.15.137) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 30 Oct 2018 17:30:42 +0000 Received: by gcc1-power7.osuosl.org (Postfix, from userid 10019) id CFDC1124089F; Tue, 30 Oct 2018 17:30:40 +0000 (UTC) From: Segher Boessenkool To: gcc-patches@gcc.gnu.org Cc: jakub@redhat.com, Segher Boessenkool Subject: [PATCH 1/2] asm qualifiers (PR55681) Date: Tue, 30 Oct 2018 18:56:00 -0000 Message-Id: In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes X-SW-Source: 2018-10/txt/msg01939.txt.bz2 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 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