From 323d171f9019dff605e78c6d027348e8d38b7e00 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 20 Jul 2016 16:16:40 +0200 Subject: [PATCH] re PR c++/71909 (g++ accepts an unreachable function catch block that lacks a corresponding try) 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 | 7 +++++ gcc/cp/parser.c | 42 ++++++++++++++++++++++++++-- gcc/testsuite/ChangeLog | 7 ++++- gcc/testsuite/g++.dg/parse/pr71909.C | 22 +++++++++++++++ gcc/testsuite/g++.dg/tm/pr71909.C | 18 ++++++++++++ 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/pr71909.C create mode 100644 gcc/testsuite/g++.dg/tm/pr71909.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 333ac411b609..e1de805d37ec 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-07-20 Jakub Jelinek + + 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 Backported from mainline diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e92fff78a8f5..03b93ab2d751 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 888edfbc1d7a..6d6e08fafbcd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-07-20 Jakub Jelinek + + PR c++/71909 + * g++.dg/parse/pr71909.C: New test. + * g++.dg/tm/pr71909.C: New test. + 2016-07-20 Martin Jambor PR fortran/71688 @@ -32,7 +38,6 @@ PR fortran/71623 * gfortran.dg/deferred_character_18.f90: New test. - 2016-07-12 Segher Boessenkool 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 index 000000000000..ee592bf8e2b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr71909.C @@ -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 index 000000000000..941f23151701 --- /dev/null +++ b/gcc/testsuite/g++.dg/tm/pr71909.C @@ -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 (...) {} -- 2.47.2