Commit be977d08 by Jason Merrill Committed by Paolo Carlini

re PR c++/71169 (ICE on invalid C++ code in pop_nested_class (cp/class.c:7785))

/cp
2018-03-09  Jason Merrill  <jason@redhat.com>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71169
	PR c++/71832
	* pt.c (any_erroneous_template_args_p): New.
	* cp-tree.h (any_erroneous_template_args_p): Declare it.
	* parser.c (cp_parser_class_specifier_1): Use it.

/testsuite
2018-03-09  Jason Merrill  <jason@redhat.com>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71169
	PR c++/71832
	* g++.dg/cpp0x/pr71169.C: New.
	* g++.dg/cpp0x/pr71169-2.C: Likewise.
	* g++.dg/cpp0x/pr71832.C: Likewise.

Co-Authored-By: Paolo Carlini <paolo.carlini@oracle.com>

From-SVN: r258401
parent 00d7fc28
2018-03-10 Jason Merrill <jason@redhat.com>
Paolo Carlini <paolo.carlini@oracle.com>
PR c++/71169
PR c++/71832
* pt.c (any_erroneous_template_args_p): New.
* cp-tree.h (any_erroneous_template_args_p): Declare it.
* parser.c (cp_parser_class_specifier_1): Use it.
2018-03-09 Jason Merrill <jason@redhat.com> 2018-03-09 Jason Merrill <jason@redhat.com>
PR c++/84726 - unnecessary capture of constant vars. PR c++/84726 - unnecessary capture of constant vars.
......
...@@ -6569,6 +6569,7 @@ extern int processing_template_parmlist; ...@@ -6569,6 +6569,7 @@ extern int processing_template_parmlist;
extern bool dependent_type_p (tree); extern bool dependent_type_p (tree);
extern bool dependent_scope_p (tree); extern bool dependent_scope_p (tree);
extern bool any_dependent_template_arguments_p (const_tree); extern bool any_dependent_template_arguments_p (const_tree);
extern bool any_erroneous_template_args_p (const_tree);
extern bool dependent_template_p (tree); extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree); extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree); extern bool type_dependent_expression_p (tree);
......
...@@ -22669,6 +22669,16 @@ cp_parser_class_specifier_1 (cp_parser* parser) ...@@ -22669,6 +22669,16 @@ cp_parser_class_specifier_1 (cp_parser* parser)
cp_default_arg_entry *e; cp_default_arg_entry *e;
tree save_ccp, save_ccr; tree save_ccp, save_ccr;
if (any_erroneous_template_args_p (type))
{
/* Skip default arguments, NSDMIs, etc, in order to improve
error recovery (c++/71169, c++/71832). */
vec_safe_truncate (unparsed_funs_with_default_args, 0);
vec_safe_truncate (unparsed_nsdmis, 0);
vec_safe_truncate (unparsed_classes, 0);
vec_safe_truncate (unparsed_funs_with_definitions, 0);
}
/* In a first pass, parse default arguments to the functions. /* In a first pass, parse default arguments to the functions.
Then, in a second pass, parse the bodies of the functions. Then, in a second pass, parse the bodies of the functions.
This two-phased approach handles cases like: This two-phased approach handles cases like:
...@@ -25048,6 +25048,39 @@ any_dependent_template_arguments_p (const_tree args) ...@@ -25048,6 +25048,39 @@ any_dependent_template_arguments_p (const_tree args)
return false; return false;
} }
/* Returns true if ARGS contains any errors. */
bool
any_erroneous_template_args_p (const_tree args)
{
int i;
int j;
if (args == error_mark_node)
return true;
if (args && TREE_CODE (args) != TREE_VEC)
{
if (tree ti = get_template_info (args))
args = TI_ARGS (ti);
else
args = NULL_TREE;
}
if (!args)
return false;
for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
{
const_tree level = TMPL_ARGS_LEVEL (args, i + 1);
for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
if (error_operand_p (TREE_VEC_ELT (level, j)))
return true;
}
return false;
}
/* Returns TRUE if the template TMPL is type-dependent. */ /* Returns TRUE if the template TMPL is type-dependent. */
bool bool
......
2018-03-09 Jason Merrill <jason@redhat.com>
Paolo Carlini <paolo.carlini@oracle.com>
PR c++/71169
PR c++/71832
* g++.dg/cpp0x/pr71169.C: New.
* g++.dg/cpp0x/pr71169-2.C: Likewise.
* g++.dg/cpp0x/pr71832.C: Likewise.
2018-03-09 Peter Bergner <bergner@vnet.ibm.com> 2018-03-09 Peter Bergner <bergner@vnet.ibm.com>
PR target/83969 PR target/83969
......
// { dg-do compile { target c++11 } }
template <Preconditioner> class A { // { dg-error "declared" }
template <class = int> void m_fn1() {
m_fn1();
}
};
template<typename>
struct B
{
int f(int = 0) { return 0; }
};
int main()
{
B<int> b;
return b.f();
}
// { dg-do compile { target c++11 } }
template <Preconditioner> class A { // { dg-error "declared" }
template <class = int> void m_fn1() {
m_fn1();
}
};
// { dg-do compile { target c++11 } }
template < typename decltype (0) > struct A // { dg-error "expected|two or more" }
{
void foo () { baz (); }
template < typename ... S > void baz () {}
};
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