Commit e0672441 by Adam Butcher Committed by Adam Butcher

re PR c++/60390 ([c++1y] ICE with declaring function with auto parameter as friend)

Fix PR c++/60390

	PR c++/60390
	* parser.c (cp_parser_member_declaration): Don't allow
	finish_fully_implicit_template to consider friend declarations to be
	class member templates.
	(synthesize_implicit_template_parm): Handling winding back through class
	scope to the class being defined in order to inject a template argument
	list.

	PR c++/60390
	* g++.dg/cpp1y/pr60390.C: New testcase.

From-SVN: r208625
parent c66f2ba1
2014-03-17 Adam Butcher <adam@jessamine.co.uk>
PR c++/60390
* parser.c (cp_parser_member_declaration): Don't allow
finish_fully_implicit_template to consider friend declarations to be
class member templates.
(synthesize_implicit_template_parm): Handling winding back through class
scope to the class being defined in order to inject a template argument
list.
PR c++/60391
* parser.c (cp_parser_skip_to_end_of_block_or_statement): Unwind generic
function scope as per cp_parser_skip_to_end_of_statement.
......
......@@ -20527,8 +20527,13 @@ cp_parser_member_declaration (cp_parser* parser)
decl = grokfield (declarator, &decl_specifiers,
initializer, /*init_const_expr_p=*/true,
asm_specification, attributes);
if (parser->fully_implicit_function_template_p)
decl = finish_fully_implicit_template (parser, decl);
if (parser->fully_implicit_function_template_p)
{
if (friend_p)
finish_fully_implicit_template (parser, 0);
else
decl = finish_fully_implicit_template (parser, decl);
}
}
cp_finalize_omp_declare_simd (parser, decl);
......@@ -31982,13 +31987,32 @@ synthesize_implicit_template_parm (cp_parser *parser)
parent_scope = scope;
scope = scope->level_chain;
}
if (current_class_type && !LAMBDA_TYPE_P (current_class_type)
&& parser->num_classes_being_defined == 0)
while (scope->kind == sk_class)
{
parent_scope = scope;
scope = scope->level_chain;
}
if (current_class_type && !LAMBDA_TYPE_P (current_class_type))
{
/* If not defining a class, then any class scope is a scope level in
an out-of-line member definition. In this case simply wind back
beyond the first such scope to inject the template argument list.
Otherwise wind back to the class being defined. The latter can
occur in class member friend declarations such as:
class A {
void foo (auto);
};
class B {
friend void A::foo (auto);
};
The template argument list synthesized for the friend declaration
must be injected in the scope of 'B', just beyond the scope of 'A'
introduced by 'A::'. */
while (scope->kind == sk_class
&& !TYPE_BEING_DEFINED (scope->this_entity))
{
parent_scope = scope;
scope = scope->level_chain;
}
}
current_binding_level = scope;
......
2014-03-17 Adam Butcher <adam@jessamine.co.uk>
PR c++/60390
* g++.dg/cpp1y/pr60390.C: New testcase.
PR c++/60391
* g++.dg/cpp1y/pr60391.C: New testcase.
......
// PR c++/60390
// { dg-do compile { target c++1y } }
// { dg-options "" }
struct A
{
void foo (auto);
};
class B
{
int m;
friend void A::foo (auto);
};
void A::foo (auto i)
{
B b;
b.m = i;
}
int main ()
{
A a;
a.foo (7);
}
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