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
This commit is contained in:
parent
aa30dfadf3
commit
37a92c0ca2
@ -1,5 +1,11 @@
|
||||
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
|
||||
* operators.def: Add *_FOLD_EXPR.
|
||||
* 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,
|
||||
bool ivdep)
|
||||
{
|
||||
tree stmt, range_expr;
|
||||
cxx_binding *binding = NULL;
|
||||
tree name = NULL_TREE;
|
||||
|
||||
/* Get the range declaration momentarily out of the way so that
|
||||
the range expression doesn't clash with it. */
|
||||
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))
|
||||
{
|
||||
@ -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. */
|
||||
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
|
||||
at instantiation. If not, it is done just ahead. */
|
||||
@ -12437,8 +12446,15 @@ cp_parser_simple_declaration (cp_parser* parser,
|
||||
if (token->type == CPP_COMMA)
|
||||
/* will be consumed next time around */;
|
||||
/* If it's a `;', we are done. */
|
||||
else if (token->type == CPP_SEMICOLON || maybe_range_for_decl)
|
||||
else if (token->type == CPP_SEMICOLON)
|
||||
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. */
|
||||
else
|
||||
{
|
||||
|
9
gcc/testsuite/g++.dg/cpp0x/range-for31.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/range-for31.C
Normal file
@ -0,0 +1,9 @@
|
||||
// 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 @@
|
||||
|
||||
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" }
|
||||
;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user