aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-03-09 18:03:06 -0500
committerPaolo Carlini <paolo@gcc.gnu.org>2018-03-09 23:03:06 +0000
commitbe977d080fd58b54984bb487b0acaf0739a26899 (patch)
tree9dde4808887b8a5dd93f0a1107045f00a42776f3
parent00d7fc28dc5e2071ada7c44de545c3ae408a0df3 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/parser.c10
-rw-r--r--gcc/cp/pt.c33
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr71169-2.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr71169.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr71832.C7
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 () {}
+};