diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2018-12-06 18:47:52 +0100 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2018-12-06 18:47:52 +0100 |
commit | 30bd42b979140de02d343bb1014e9aece2e683c1 (patch) | |
tree | 9425afdd3c7769016beca989282d7389695f48ac /gcc/c/c-parser.c | |
parent | 415937b37d77d7a8ec11273060d45a04b1f3ca62 (diff) | |
download | gcc-30bd42b979140de02d343bb1014e9aece2e683c1.zip gcc-30bd42b979140de02d343bb1014e9aece2e683c1.tar.gz gcc-30bd42b979140de02d343bb1014e9aece2e683c1.tar.bz2 |
asm qualifiers (PR55681)
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
"goto" has to be last.
This patch changes things so that only "asm-qualifiers" are allowed,
that is "volatile" and "goto", in any combination, in any order, but
without repetitions.
PR inline-asm/55681
* doc/extend.texi (Basic Asm): Update grammar.
(Extended Asm): Update grammar.
gcc/c/
PR inline-asm/55681
* c-parser.c (c_parser_asm_statement): Update grammar. Allow any
combination of volatile and goto, in any order, without repetitions.
gcc/cp/
PR inline-asm/55681
* parser.c (cp_parser_asm_definition): Update grammar. Allow any
combination of volatile and goto, in any order, without repetitions.
gcc/testsuite/
PR inline-asm/55681
* gcc.dg/asm-qual-1.c: Test that "const" and "restrict" are refused.
* gcc.dg/asm-qual-2.c: New test, test that asm-qualifiers are allowed
in any order, but that duplicates are not allowed.
From-SVN: r266859
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r-- | gcc/c/c-parser.c | 74 |
1 files changed, 43 insertions, 31 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 0d7fcc0..a4a8745 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -6329,60 +6329,72 @@ 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: + volatile + 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 - Qualifiers other than volatile are accepted in the syntax but - warned for. */ + 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. + Duplicate asm-qualifiers are not allowed. */ static tree c_parser_asm_statement (c_parser *parser) { tree quals, str, outputs, inputs, clobbers, labels, ret; - bool simple, is_goto; + bool simple, is_volatile, is_goto; location_t asm_loc = c_parser_peek_token (parser)->location; int section, nsections; 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_volatile = false; 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: + if (!is_volatile) + { + is_volatile = true; + quals = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + } + else + done = true; + break; + case RID_GOTO: + if (!is_goto) + { + is_goto = true; + c_parser_consume_token (parser); + } + else + done = true; + break; + default: + done = true; + } /* ??? Follow the C++ parser rather than using the lex_untranslated_string kludge. */ |