* [C++ PATCH] cp_parser_save_member_function_body fix (PR c++/71909)
@ 2016-07-18 21:14 Jakub Jelinek
2016-07-20 13:45 ` Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2016-07-18 21:14 UTC (permalink / raw)
To: Jason Merrill, Torvald Riegel; +Cc: gcc-patches
Hi!
This patch fixes two issues:
1) as shown in the first testcase, cp_parser_save_member_function_body
adds the catch (....) { ... } tokens into the saved token range
even when there is no function try block (missing try keyword)
2) if the method starts with __transaction_{atomic,relaxed}, and
e.g. contains {}s somewhere in the mem-initializers, then
cp_parser_save_member_function_body stops saving the tokens early
instead of late
The following patch attempts to handle the same cases
cp_parser_function_definition_after_declarator handles (ok, ignores
the already unsupported return extension) - note that
cp_parser_txn_attribute_opt handles only a small subset of C++11 attributes
(and only once, not multiple times).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2016-07-18 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.
* g++.dg/parse/pr71909.C: New test.
* g++.dg/tm/pr71909.C: New test.
--- gcc/cp/parser.c.jj 2016-07-16 10:41:04.000000000 +0200
+++ gcc/cp/parser.c 2016-07-18 11:47:49.487748010 +0200
@@ -26044,6 +26044,7 @@ cp_parser_save_member_function_body (cp_
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_
/* 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_
}
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
--- gcc/testsuite/g++.dg/parse/pr71909.C.jj 2016-07-18 11:55:51.169600236 +0200
+++ gcc/testsuite/g++.dg/parse/pr71909.C 2016-07-18 11:57:09.555599364 +0200
@@ -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;
+};
--- gcc/testsuite/g++.dg/tm/pr71909.C.jj 2016-07-18 12:01:59.888892245 +0200
+++ gcc/testsuite/g++.dg/tm/pr71909.C 2016-07-18 12:01:14.000000000 +0200
@@ -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 (...) {}
Jakub
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [C++ PATCH] cp_parser_save_member_function_body fix (PR c++/71909)
2016-07-18 21:14 [C++ PATCH] cp_parser_save_member_function_body fix (PR c++/71909) Jakub Jelinek
@ 2016-07-20 13:45 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2016-07-20 13:45 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Torvald Riegel, gcc-patches List
OK.
On Mon, Jul 18, 2016 at 5:14 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> This patch fixes two issues:
> 1) as shown in the first testcase, cp_parser_save_member_function_body
> adds the catch (....) { ... } tokens into the saved token range
> even when there is no function try block (missing try keyword)
> 2) if the method starts with __transaction_{atomic,relaxed}, and
> e.g. contains {}s somewhere in the mem-initializers, then
> cp_parser_save_member_function_body stops saving the tokens early
> instead of late
>
> The following patch attempts to handle the same cases
> cp_parser_function_definition_after_declarator handles (ok, ignores
> the already unsupported return extension) - note that
> cp_parser_txn_attribute_opt handles only a small subset of C++11 attributes
> (and only once, not multiple times).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2016-07-18 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.
>
> * g++.dg/parse/pr71909.C: New test.
> * g++.dg/tm/pr71909.C: New test.
>
> --- gcc/cp/parser.c.jj 2016-07-16 10:41:04.000000000 +0200
> +++ gcc/cp/parser.c 2016-07-18 11:47:49.487748010 +0200
> @@ -26044,6 +26044,7 @@ cp_parser_save_member_function_body (cp_
> 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_
> /* 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_
> }
> 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
> --- gcc/testsuite/g++.dg/parse/pr71909.C.jj 2016-07-18 11:55:51.169600236 +0200
> +++ gcc/testsuite/g++.dg/parse/pr71909.C 2016-07-18 11:57:09.555599364 +0200
> @@ -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;
> +};
> --- gcc/testsuite/g++.dg/tm/pr71909.C.jj 2016-07-18 12:01:59.888892245 +0200
> +++ gcc/testsuite/g++.dg/tm/pr71909.C 2016-07-18 12:01:14.000000000 +0200
> @@ -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 (...) {}
>
> Jakub
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-07-20 13:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-18 21:14 [C++ PATCH] cp_parser_save_member_function_body fix (PR c++/71909) Jakub Jelinek
2016-07-20 13:45 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).