]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/71909 (g++ accepts an unreachable function catch block that lacks a corresp...
authorJakub Jelinek <jakub@redhat.com>
Wed, 20 Jul 2016 14:16:40 +0000 (16:16 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 20 Jul 2016 14:16:40 +0000 (16:16 +0200)
PR c++/71909
* parser.c (cp_parser_save_member_function_body): Consume
__transaction_relaxed or __transaction_atomic with optional
attribute.  Only skip catch with block if try keyword is seen.

* g++.dg/parse/pr71909.C: New test.
* g++.dg/tm/pr71909.C: New test.

From-SVN: r238526

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/pr71909.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tm/pr71909.C [new file with mode: 0644]

index 333ac411b609587602a1230af5ed4aae229a3ca0..e1de805d37eca201b6e66f7e3e3827f5dbb8ccd9 100644 (file)
@@ -1,3 +1,10 @@
+2016-07-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/71909
+       * parser.c (cp_parser_save_member_function_body): Consume
+       __transaction_relaxed or __transaction_atomic with optional
+       attribute.  Only skip catch with block if try keyword is seen.
+
 2016-07-19  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
index e92fff78a8f5201147faafa5dbed403ee9e1ba79..03b93ab2d751fba418e93346ec3fe16505f58d29 100644 (file)
@@ -23964,6 +23964,7 @@ cp_parser_save_member_function_body (cp_parser* parser,
   cp_token *first;
   cp_token *last;
   tree fn;
+  bool function_try_block = false;
 
   /* Create the FUNCTION_DECL.  */
   fn = grokmethod (decl_specifiers, declarator, attributes);
@@ -23984,9 +23985,43 @@ cp_parser_save_member_function_body (cp_parser* parser,
   /* Save away the tokens that make up the body of the
      function.  */
   first = parser->lexer->next_token;
+
+  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_RELAXED))
+    cp_lexer_consume_token (parser->lexer);
+  else if (cp_lexer_next_token_is_keyword (parser->lexer,
+                                          RID_TRANSACTION_ATOMIC))
+    {
+      cp_lexer_consume_token (parser->lexer);
+      /* Match cp_parser_txn_attribute_opt [[ identifier ]].  */
+      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)
+         && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE)
+         && (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME)
+             || cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD))
+         && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_SQUARE)
+         && cp_lexer_nth_token_is (parser->lexer, 5, CPP_CLOSE_SQUARE))
+       {
+         cp_lexer_consume_token (parser->lexer);
+         cp_lexer_consume_token (parser->lexer);
+         cp_lexer_consume_token (parser->lexer);
+         cp_lexer_consume_token (parser->lexer);
+         cp_lexer_consume_token (parser->lexer);
+       }
+      else
+       while (cp_next_tokens_can_be_gnu_attribute_p (parser)
+              && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
+         {
+           cp_lexer_consume_token (parser->lexer);
+           if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
+             break;
+         }
+    }
+
   /* Handle function try blocks.  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
-    cp_lexer_consume_token (parser->lexer);
+    {
+      cp_lexer_consume_token (parser->lexer);
+      function_try_block = true;
+    }
   /* We can have braced-init-list mem-initializers before the fn body.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
     {
@@ -24004,8 +24039,9 @@ cp_parser_save_member_function_body (cp_parser* parser,
     }
   cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
   /* Handle function try blocks.  */
-  while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
-    cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
+  if (function_try_block)
+    while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
+      cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
   last = parser->lexer->next_token;
 
   /* Save away the inline definition; we will process it when the
index 888edfbc1d7a9d8c644ece2da113c1dfcc8426f6..6d6e08fafbcd2755fe13bec92db0cb550bc58d57 100644 (file)
@@ -1,3 +1,9 @@
+2016-07-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/71909
+       * g++.dg/parse/pr71909.C: New test.
+       * g++.dg/tm/pr71909.C: New test.
+
 2016-07-20  Martin Jambor  <mjambor@suse.cz>
 
         PR fortran/71688
@@ -32,7 +38,6 @@
        PR fortran/71623
        * gfortran.dg/deferred_character_18.f90: New test.
 
-
 2016-07-12  Segher Boessenkool  <segher@kernel.crashing.org>
 
        Backport from mainline
diff --git a/gcc/testsuite/g++.dg/parse/pr71909.C b/gcc/testsuite/g++.dg/parse/pr71909.C
new file mode 100644 (file)
index 0000000..ee592bf
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/71909
+// { dg-do compile }
+
+struct S
+{
+  S () try : m (0) {}
+  catch (...) {}
+  void foo () try {}
+  catch (int) {}
+  catch (...) {}
+  int m;
+};
+
+struct T
+{
+  T () : m (0) {}
+  catch (...) {}       // { dg-error "expected unqualified-id before" }
+  void foo () {}
+  catch (int) {}       // { dg-error "expected unqualified-id before" }
+  catch (...) {}       // { dg-error "expected unqualified-id before" }
+  int m;
+};
diff --git a/gcc/testsuite/g++.dg/tm/pr71909.C b/gcc/testsuite/g++.dg/tm/pr71909.C
new file mode 100644 (file)
index 0000000..941f231
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/71909
+// { dg-do compile { target c++11 } }
+// { dg-options "-fgnu-tm" }
+
+struct S
+{
+  S () __transaction_atomic [[outer]] try : m {0} {} catch (int) {} catch (...) {}
+  int m;
+};
+
+struct T
+{
+  T () __transaction_atomic __attribute__((outer)) try : m {0} {} catch (int) {} catch (...) {}
+  int m;
+};
+
+void foo () __transaction_atomic [[outer]] try {} catch (int) {} catch (...) {}
+void bar () __transaction_atomic __attribute__((outer)) try {} catch (int) {} catch (...) {}