Commit 7419f441 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 109d2197
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
......
......@@ -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
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.
PR c++/50060
* g++.dg/cpp0x/constexpr-50060.C: New test.
* g++.dg/cpp1y/constexpr-50060.C: New test.
......
// 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;
};
// 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 (...) {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment