diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-07-20 16:01:30 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-07-20 16:01:30 +0200 |
commit | 7419f4417a33ff9143317794aa985f7681d1e2a0 (patch) | |
tree | 1d243343f1193d9977b24d69c9e1935d177ad3d1 /gcc/cp | |
parent | 109d2197c31b766daf9c7b138bc7eeaab12985df (diff) | |
download | gcc-7419f4417a33ff9143317794aa985f7681d1e2a0.zip gcc-7419f4417a33ff9143317794aa985f7681d1e2a0.tar.gz gcc-7419f4417a33ff9143317794aa985f7681d1e2a0.tar.bz2 |
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: r238521
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/parser.c | 42 |
2 files changed, 44 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7b90320..cc5df6e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +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. + PR c++/50060 * constexpr.c (cxx_eval_builtin_function_call): Pass false as lval when evaluating call arguments. Use fold_builtin_call_array instead diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0a0f67b..84dad48 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -26044,6 +26044,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); @@ -26065,9 +26066,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)) { @@ -26085,8 +26120,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 |