From 30bd42b979140de02d343bb1014e9aece2e683c1 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Thu, 6 Dec 2018 18:47:52 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++ gcc/c/ChangeLog | 6 +++ gcc/c/c-parser.c | 74 ++++++++++++++++------------- gcc/cp/ChangeLog | 6 +++ gcc/cp/parser.c | 77 ++++++++++++++++++++----------- gcc/doc/extend.texi | 8 ++-- gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.dg/asm-qual-1.c | 10 ++-- gcc/testsuite/gcc.dg/asm-qual-2.c | 21 +++++++++ 9 files changed, 152 insertions(+), 63 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/asm-qual-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b145911548..acf327cd8ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-12-06 Segher Boessenkool + + PR inline-asm/55681 + * doc/extend.texi (Basic Asm): Update grammar. + (Extended Asm): Update grammar. + 2018-12-06 Iain Sandoe PR target/78444 diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 6f0f67cc190..c54223de26d 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-12-06 Segher Boessenkool + + 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. + 2018-12-04 James Norris Cesar Philippidis Julian Brown diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 0d7fcc0f722..a4a8745acff 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. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bda9c59411d..26b83cffdff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-12-06 Segher Boessenkool + + PR inline-asm/55681 + * parser.c (cp_parser_asm_definition): Update grammar. Allow any + combination of volatile and goto, in any order, without repetitions. + 2018-12-06 David Malcolm PR c++/85110 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ac19cb4b9bb..ac953d0c611 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19590,22 +19590,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) @@ -19634,23 +19646,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; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e27bc022eb8..70c46cff569 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -8447,7 +8447,7 @@ for a C symbol, or to place a C variable in a specific register. A basic @code{asm} statement has the following syntax: @example -asm @r{[} volatile @r{]} ( @var{AssemblerInstructions} ) +asm @var{asm-qualifiers} ( @var{AssemblerInstructions} ) @end example The @code{asm} keyword is a GNU extension. @@ -8575,17 +8575,19 @@ Extended @code{asm} syntax uses colons (@samp{:}) to delimit the operand parameters after the assembler template: @example -asm @r{[}volatile@r{]} ( @var{AssemblerTemplate} +asm @var{asm-qualifiers} ( @var{AssemblerTemplate} : @var{OutputOperands} @r{[} : @var{InputOperands} @r{[} : @var{Clobbers} @r{]} @r{]}) -asm @r{[}volatile@r{]} goto ( @var{AssemblerTemplate} +asm @var{asm-qualifiers} ( @var{AssemblerTemplate} : : @var{InputOperands} : @var{Clobbers} : @var{GotoLabels}) @end example +where in the last form, @var{asm-qualifiers} contains @code{goto} (and in the +first form, not). The @code{asm} keyword is a GNU extension. When writing code that can be compiled with @option{-ansi} and the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0272bbe0605..11152d0ae30 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-12-06 Segher Boessenkool + + 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. + 2018-12-06 Jeff Law PR testsuite/86540 diff --git a/gcc/testsuite/gcc.dg/asm-qual-1.c b/gcc/testsuite/gcc.dg/asm-qual-1.c index 5ec9a29a910..cb37283d13f 100644 --- a/gcc/testsuite/gcc.dg/asm-qual-1.c +++ b/gcc/testsuite/gcc.dg/asm-qual-1.c @@ -1,4 +1,4 @@ -/* Test that qualifiers other than volatile are ignored on asm. */ +/* Test that qualifiers other than volatile are disallowed on asm. */ /* Origin: Joseph Myers */ /* { dg-do compile } */ /* { dg-options "-std=gnu99" } */ @@ -7,6 +7,10 @@ void f (void) { asm volatile (""); - asm const (""); /* { dg-warning "const qualifier ignored on asm" } */ - asm restrict (""); /* { dg-warning "restrict qualifier ignored on asm" } */ + + asm const (""); /* { dg-error {expected '\(' before 'const'} } */ + /* { dg-error {expected identifier} {} {target *-*-*} .-1 } */ + + asm restrict (""); /* { dg-error {expected '\(' before 'restrict'} } */ + /* { dg-error {expected identifier} {} {target *-*-*} .-1 } */ } diff --git a/gcc/testsuite/gcc.dg/asm-qual-2.c b/gcc/testsuite/gcc.dg/asm-qual-2.c new file mode 100644 index 00000000000..37df2ad2b8d --- /dev/null +++ b/gcc/testsuite/gcc.dg/asm-qual-2.c @@ -0,0 +1,21 @@ +/* Test that qualifiers on asm are allowed in any order. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +void +f (void) +{ + asm volatile goto ("" :::: lab); + asm goto volatile ("" :::: lab); + + /* Duplicates are not allowed. */ + asm goto volatile volatile ("" :::: lab); /* { dg-error "" } */ + asm volatile goto volatile ("" :::: lab); /* { dg-error "" } */ + asm volatile volatile goto ("" :::: lab); /* { dg-error "" } */ + asm goto goto volatile ("" :::: lab); /* { dg-error "" } */ + asm goto volatile goto ("" :::: lab); /* { dg-error "" } */ + asm volatile goto goto ("" :::: lab); /* { dg-error "" } */ + +lab: + ; +} -- 2.30.2