asm qualifiers (PR55681)
authorSegher Boessenkool <segher@kernel.crashing.org>
Thu, 6 Dec 2018 17:47:52 +0000 (18:47 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Thu, 6 Dec 2018 17:47:52 +0000 (18:47 +0100)
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
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/asm-qual-1.c
gcc/testsuite/gcc.dg/asm-qual-2.c [new file with mode: 0644]

index 4b145911548e3e6cc622262889e29718346f5fac..acf327cd8ca6832dd4c35f36eb8e15a36dd7d17b 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-06  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR inline-asm/55681
+       * doc/extend.texi (Basic Asm): Update grammar.
+       (Extended Asm): Update grammar.
+
 2018-12-06  Iain Sandoe  <iain@sandoe.co.uk>
 
        PR target/78444
index 6f0f67cc190128ec522efde9fcc9d58e368ba81b..c54223de26d2e3b7e5eda204f5c5f1254f4e635f 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-06  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       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  <jnorris@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
            Julian Brown  <julian@codesourcery.com>
index 0d7fcc0f7228535978993d29d439f034478d325b..a4a8745acffb1d391e74b6ab80c6c42eb94dd429 100644 (file)
@@ -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.  */
index bda9c59411d82d857af71e9e797d16414ca6112a..26b83cffdff88cf9a82a520a4312173d8fc9c5ba 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-06  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       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  <dmalcolm@redhat.com>
 
        PR c++/85110
index ac19cb4b9bb51bda0db332f7a16d6631e7b19589..ac953d0c61119c5751d41d677f3299bfd1469644 100644 (file)
@@ -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;
index e27bc022eb8d287f4ab0645db73ce18b84655d57..70c46cff5691e9d76364b2289b4fbf9105e3dd1b 100644 (file)
@@ -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
index 0272bbe06050ba2388c0a92043958522f2a02999..11152d0ae3047aa6ec307ad12a882520b726106b 100644 (file)
@@ -1,3 +1,10 @@
+2018-12-06  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       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  <law@redhat.com>
 
        PR testsuite/86540
index 5ec9a29a9108386334e5e6dc6c78f2e74a8d1222..cb37283d13f943d4f1bfc3751498b063d9653b1f 100644 (file)
@@ -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 <joseph@codesourcery.com> */
 /* { 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 (file)
index 0000000..37df2ad
--- /dev/null
@@ -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:
+  ;
+}