Commit 37a92c0c by Jason Merrill Committed by Jason Merrill

PR c++/71604 - type definition in range-based for

	PR c++/54430
	* parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly.
	(cp_parser_simple_declaration): Diagnose type definition in
	for-range-declaration.

From-SVN: r238391
parent aa30dfad
2016-07-15 Jason Merrill <jason@redhat.com> 2016-07-15 Jason Merrill <jason@redhat.com>
PR c++/71604
PR c++/54430
* parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly.
(cp_parser_simple_declaration): Diagnose type definition in
for-range-declaration.
PR c++/71711 PR c++/71711
* operators.def: Add *_FOLD_EXPR. * operators.def: Add *_FOLD_EXPR.
* cp-tree.h (FOLD_EXPR_P): Parenthesize. * cp-tree.h (FOLD_EXPR_P): Parenthesize.
......
...@@ -11187,11 +11187,17 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, ...@@ -11187,11 +11187,17 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
bool ivdep) bool ivdep)
{ {
tree stmt, range_expr; tree stmt, range_expr;
cxx_binding *binding = NULL;
tree name = NULL_TREE;
/* Get the range declaration momentarily out of the way so that /* Get the range declaration momentarily out of the way so that
the range expression doesn't clash with it. */ the range expression doesn't clash with it. */
if (range_decl != error_mark_node) if (range_decl != error_mark_node)
pop_binding (DECL_NAME (range_decl), range_decl); {
name = DECL_NAME (range_decl);
binding = IDENTIFIER_BINDING (name);
IDENTIFIER_BINDING (name) = binding->previous;
}
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{ {
...@@ -11203,7 +11209,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, ...@@ -11203,7 +11209,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
/* Put the range declaration back into scope. */ /* Put the range declaration back into scope. */
if (range_decl != error_mark_node) if (range_decl != error_mark_node)
push_binding (DECL_NAME (range_decl), range_decl, current_binding_level); {
binding->previous = IDENTIFIER_BINDING (name);
IDENTIFIER_BINDING (name) = binding;
}
/* If in template, STMT is converted to a normal for-statement /* If in template, STMT is converted to a normal for-statement
at instantiation. If not, it is done just ahead. */ at instantiation. If not, it is done just ahead. */
...@@ -12437,8 +12446,15 @@ cp_parser_simple_declaration (cp_parser* parser, ...@@ -12437,8 +12446,15 @@ cp_parser_simple_declaration (cp_parser* parser,
if (token->type == CPP_COMMA) if (token->type == CPP_COMMA)
/* will be consumed next time around */; /* will be consumed next time around */;
/* If it's a `;', we are done. */ /* If it's a `;', we are done. */
else if (token->type == CPP_SEMICOLON || maybe_range_for_decl) else if (token->type == CPP_SEMICOLON)
break; break;
else if (maybe_range_for_decl)
{
if (declares_class_or_enum && token->type == CPP_COLON)
permerror (decl_specifiers.locations[ds_type_spec],
"types may not be defined in a for-range-declaration");
break;
}
/* Anything else is an error. */ /* Anything else is an error. */
else else
{ {
// PR c++/71604
// { dg-do compile { target c++11 } }
void foo ()
{
int a[2] = { 1, 2 };
for (struct S { S (int) {} } S : a) // { dg-error "types may not be defined" }
;
}
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
void test() void test()
{ {
for (struct S { } *x : { (S*)0, (S*)0 } ) for (struct S { } *x : { (S*)0, (S*)0 } ) // { dg-error "types may not be defined" }
; ;
for (struct S { } x : { S(), S() } ) for (struct S { } x : { S(), S() } ) // { dg-error "types may not be defined" }
; ;
} }
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