Commit 0dca5025 by Adam Butcher Committed by Adam Butcher

Refactor implicit function template implementation and fix 58534, 58536, 58548, 58549 and 58637.

gcc/
	* tree.c (grow_tree_vec_stat): New function ...
	* tree.h (grow_tree_vec_stat) (grow_tree_vec): ... and its declaration
	and macro front-end.

gcc/cp/
	PR c++/58534
	PR c++/58536
	PR c++/58548
	PR c++/58549
	PR c++/58637
	* parser.h (struct cp_parser): New members implicit_template_parms,
	implicit_template_scope and auto_is_implicit_function_template_parm_p.
	* parser.c (add_implicit_template_parms): Refactor as ...
	(synthesize_implicit_template_parm): ... this to append a new template
	type parm to the current template parameter list (introducing a new list
	if necessary).  Removed push_deferring_access_checks.
	(finish_fully_implicit_template): Removed pop_deferring_access_checks.
	(cp_parser_new): Initialize new cp_parser members.
	(cp_parser_parameter_declaration_clause): Consider auto as implicit
	template parm when parsing a parameter declaration (unless parsing an
	explicit specialization).
	(cp_parser_parameter_declaration_list): Remove local
	implicit_template_parms counter and reset cp_parser implicit template
	state when complete.
	(cp_parser_lambda_expression): Reset implicit template cp_parser members
	whilst generating lambda class.
	(cp_parser_function_definition_after_declarator): Reset implicit
	template cp_parser members whilst parsing function definition.
	(make_generic_type_name): Respell '<autoN>' as 'auto:N' which works
	better with template diagnostics.
	(cp_parser_simple_type_specifier): Synthesize implicit template parm on
	parsing 'auto' if auto_is_implicit_function_template_parm_p and provide
	diagnostics ...
	* decl.c (grokdeclarator): ... that were previously done here.

gcc/testsuite/g++.dg/
	* cpp1y/pr58534.C: New testcase.
	* cpp1y/pr58536.C: New testcase.
	* cpp1y/pr58548.C: New testcase.
	* cpp1y/pr58549.C: New testcase.
	* cpp1y/pr58637.C: New testcase.

From-SVN: r204714
parent 27297d2d
2013-11-12 Adam Butcher <adam@jessamine.co.uk>
* tree.c (grow_tree_vec_stat): New function ...
* tree.h (grow_tree_vec_stat) (grow_tree_vec): ... and its declaration
and macro front-end.
2013-11-12 Marek Polacek <polacek@redhat.com>
* final.c (update_alignments): Initialize label to NULL_RTX.
2013-11-12 Adam Butcher <adam@jessamine.co.uk>
PR c++/58534
PR c++/58536
PR c++/58548
PR c++/58549
PR c++/58637
* parser.h (struct cp_parser): New members implicit_template_parms,
implicit_template_scope and auto_is_implicit_function_template_parm_p.
* parser.c (add_implicit_template_parms): Refactor as ...
(synthesize_implicit_template_parm): ... this to append a new template
type parm to the current template parameter list (introducing a new list
if necessary). Removed push_deferring_access_checks.
(finish_fully_implicit_template): Removed pop_deferring_access_checks.
(cp_parser_new): Initialize new cp_parser members.
(cp_parser_parameter_declaration_clause): Consider auto as implicit
template parm when parsing a parameter declaration (unless parsing an
explicit specialization).
(cp_parser_parameter_declaration_list): Remove local
implicit_template_parms counter and reset cp_parser implicit template
state when complete.
(cp_parser_lambda_expression): Reset implicit template cp_parser members
whilst generating lambda class.
(cp_parser_function_definition_after_declarator): Reset implicit
template cp_parser members whilst parsing function definition.
(make_generic_type_name): Respell '<autoN>' as 'auto:N' which works
better with template diagnostics.
(cp_parser_simple_type_specifier): Synthesize implicit template parm on
parsing 'auto' if auto_is_implicit_function_template_parm_p and provide
diagnostics ...
* decl.c (grokdeclarator): ... that were previously done here.
2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57734
......
......@@ -10381,33 +10381,11 @@ grokdeclarator (const cp_declarator *declarator,
if (type_uses_auto (type))
{
if (template_parm_flag)
{
error ("template parameter declared %<auto%>");
type = error_mark_node;
}
else if (decl_context == CATCHPARM)
{
error ("catch parameter declared %<auto%>");
type = error_mark_node;
}
else if (current_class_type && LAMBDA_TYPE_P (current_class_type))
{
if (cxx_dialect < cxx1y)
pedwarn (location_of (type), 0,
"use of %<auto%> in lambda parameter declaration "
"only available with "
"-std=c++1y or -std=gnu++1y");
}
else if (cxx_dialect < cxx1y)
pedwarn (location_of (type), 0,
"use of %<auto%> in parameter declaration "
"only available with "
"-std=c++1y or -std=gnu++1y");
if (cxx_dialect >= cxx1y)
error ("%<auto%> parameter not permitted in this context");
else
pedwarn (location_of (type), OPT_Wpedantic,
"ISO C++ forbids use of %<auto%> in parameter "
"declaration");
error ("parameter declared %<auto%>");
type = error_mark_node;
}
/* A parameter declared as an array of T is really a pointer to T.
......
......@@ -360,11 +360,30 @@ typedef struct GTY(()) cp_parser {
data structure with everything needed for parsing the clauses. */
cp_omp_declare_simd_data * GTY((skip)) omp_declare_simd;
/* Nonzero if parsing a parameter list where 'auto' should trigger an implicit
template parameter. */
bool auto_is_implicit_function_template_parm_p;
/* TRUE if the function being declared was made a template due to its
parameter list containing generic type specifiers (`auto' or concept
identifiers) rather than an explicit template parameter list. */
bool fully_implicit_function_template_p;
/* Tracks the function's template parameter list when declaring a function
using generic type parameters. This is either a new chain in the case of a
fully implicit function template or an extension of the function's existing
template parameter list. This is tracked to optimize calls subsequent
calls to synthesize_implicit_template_parm during
cp_parser_parameter_declaration. */
tree implicit_template_parms;
/* The scope into which an implicit template parameter list has been
introduced or an existing template parameter list is being extended with
implicit template paramaters. In most cases this is the sk_function_parms
scope containing the use of a generic type. In the case of an out-of-line
member definition using a generic type, it is the sk_class scope. */
cp_binding_level* implicit_template_scope;
} cp_parser;
/* In parser.c */
......
2013-11-12 Adam Butcher <adam@jessamine.co.uk>
PR c++/58534
PR c++/58536
PR c++/58548
PR c++/58549
PR c++/58637
* g++.dg/cpp1y/pr58534.C: New testcase.
* g++.dg/cpp1y/pr58536.C: New testcase.
* g++.dg/cpp1y/pr58548.C: New testcase.
* g++.dg/cpp1y/pr58549.C: New testcase.
* g++.dg/cpp1y/pr58637.C: New testcase.
2013-11-12 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/c90-thread-local-1.c, gcc.dg/c99-thread-local-1.c,
......
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
// PR c++/58534
template<typename> void foo(const auto&) {}
template<typename, typename...T> void foo(const auto&, T...) {}
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
// PR c++/58536
struct A
{
A(auto);
};
A::A(auto) {}
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
// PR c++/58548
void foo(auto)
{
struct A { int i; };
}
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
// PR c++/58549
void foo(auto)
{
void bar();
}
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
// PR c++/58637
template<> void foo(auto); // { dg-error "auto|not a template" }
......@@ -1864,6 +1864,28 @@ make_tree_vec_stat (int len MEM_STAT_DECL)
return t;
}
/* Grow a TREE_VEC node to new length LEN. */
tree
grow_tree_vec_stat (tree v, int len MEM_STAT_DECL)
{
gcc_assert (TREE_CODE (v) == TREE_VEC);
int oldlen = TREE_VEC_LENGTH (v);
gcc_assert (len > oldlen);
int oldlength = (oldlen - 1) * sizeof (tree) + sizeof (struct tree_vec);
int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
record_node_allocation_statistics (TREE_VEC, length - oldlength);
v = (tree) ggc_realloc_stat (v, length PASS_MEM_STAT);
TREE_VEC_LENGTH (v) = len;
return v;
}
/* Return 1 if EXPR is the integer constant zero or a complex constant
of zero. */
......
......@@ -3430,6 +3430,11 @@ extern tree make_tree_binfo_stat (unsigned MEM_STAT_DECL);
extern tree make_tree_vec_stat (int MEM_STAT_DECL);
#define make_tree_vec(t) make_tree_vec_stat (t MEM_STAT_INFO)
/* Grow a TREE_VEC. */
extern tree grow_tree_vec_stat (tree v, int MEM_STAT_DECL);
#define grow_tree_vec(v, t) grow_tree_vec_stat (v, t MEM_STAT_INFO)
/* Return the (unique) IDENTIFIER_NODE node for a given name.
The name is supplied as a char *. */
......
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