re PR c++/71169 (ICE on invalid C++ code in pop_nested_class (cp/class.c:7785))
authorJason Merrill <jason@redhat.com>
Fri, 9 Mar 2018 23:03:06 +0000 (18:03 -0500)
committerPaolo Carlini <paolo@gcc.gnu.org>
Fri, 9 Mar 2018 23:03:06 +0000 (23:03 +0000)
/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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/pr71169-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/pr71169.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/pr71832.C [new file with mode: 0644]

index 09bd33184820116d8414fed2ff5589236df14902..c287232d4d24586809a53f12007ecfe57651720d 100644 (file)
@@ -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.
index 4a406d2e9f5bcd57264916ba70f18f3ba364ef1c..186a37eea6b3da8407c05d8afb4561450c42ef03 100644 (file)
@@ -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);
index a19bbe1e1d06d7a95c52d04ef87b91fd2faa9b5b..cdc6238897322b7d5c43986e984981ca3762f530 100644 (file)
@@ -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:
index 89024c10fe2ba5aa8e618c78bd987575072ff3c8..bc815d2976453dced34fa3e7a3c373727eebacb2 100644 (file)
@@ -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
index 1e99bc3139ece828ef7bda2935e80b1464dc0a32..2c07f6a11ca929591b2434296dd3048a3cf37530 100644 (file)
@@ -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 (file)
index 0000000..fa29e95
--- /dev/null
@@ -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 (file)
index 0000000..44690a9
--- /dev/null
@@ -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 (file)
index 0000000..3b85111
--- /dev/null
@@ -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 () {}
+};