diff options
author | Jason Merrill <jason@redhat.com> | 2018-03-09 18:03:06 -0500 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2018-03-09 23:03:06 +0000 |
commit | be977d080fd58b54984bb487b0acaf0739a26899 (patch) | |
tree | 9dde4808887b8a5dd93f0a1107045f00a42776f3 | |
parent | 00d7fc28dc5e2071ada7c44de545c3ae408a0df3 (diff) | |
download | gcc-be977d080fd58b54984bb487b0acaf0739a26899.zip gcc-be977d080fd58b54984bb487b0acaf0739a26899.tar.gz gcc-be977d080fd58b54984bb487b0acaf0739a26899.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/parser.c | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr71169-2.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr71169.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr71832.C | 7 |
8 files changed, 95 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 09bd3318..c287232 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +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> PR c++/84726 - unnecessary capture of constant vars. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4a406d2..186a37e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6569,6 +6569,7 @@ extern int processing_template_parmlist; extern bool dependent_type_p (tree); extern bool dependent_scope_p (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_id_p (tree, tree); extern bool type_dependent_expression_p (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a19bbe1..cdc6238 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22669,6 +22669,16 @@ cp_parser_class_specifier_1 (cp_parser* parser) cp_default_arg_entry *e; 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. Then, in a second pass, parse the bodies of the functions. This two-phased approach handles cases like: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 89024c1..bc815d2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -25048,6 +25048,39 @@ any_dependent_template_arguments_p (const_tree args) 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. */ bool diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1e99bc3..2c07f6a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +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> PR target/83969 diff --git a/gcc/testsuite/g++.dg/cpp0x/pr71169-2.C b/gcc/testsuite/g++.dg/cpp0x/pr71169-2.C new file mode 100644 index 0000000..fa29e95 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr71169-2.C @@ -0,0 +1,19 @@ +// { 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(); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/pr71169.C b/gcc/testsuite/g++.dg/cpp0x/pr71169.C new file mode 100644 index 0000000..44690a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr71169.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } + +template <Preconditioner> class A { // { dg-error "declared" } + template <class = int> void m_fn1() { + m_fn1(); + } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr71832.C b/gcc/testsuite/g++.dg/cpp0x/pr71832.C new file mode 100644 index 0000000..3b85111 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr71832.C @@ -0,0 +1,7 @@ +// { 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 () {} +}; |