diff mbox

Fix PR c++/77639 (ICE during error recovery)

Message ID 20160919120712.8930-1-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka Sept. 19, 2016, 12:07 p.m. UTC
Some syntactically invalid code can confuse the compiler into trying to
define a specialization while processing_template_parmlist != 0, during
which there is a dummy parameter level (a TREE_VEC of length 0) on
current_template_parms which the TEMPLATE_DECL of the specialization
then inherits.  This dummy parameter level is expected to appear only on
the template parms of a TEMPLATE_TEMPLATE_PARM so its appearance on a
TEMPLATE_DECL (of the bogus specialization) eventually causes an ICE.
From what I understand, a template specialization can not possibly be
defined from inside a template parameter list so this patch avoids the
ICE by avoiding to generate the bogus specialization in the first place.
Does this look OK to commit after bootstrap + regtesting?

gcc/cp/ChangeLog:

	PR c++/77639
	* pt.c (maybe_process_partial_specialization): Don't try
	defining a specialization when processing_template_parmlist.

gcc/testsuite/ChangeLog:

	PR c++/77639
	* g++.dg/template/error-recovery4.C: New test.
---
 gcc/cp/pt.c                                     | 8 ++++++++
 gcc/testsuite/g++.dg/template/error-recovery4.C | 5 +++++
 2 files changed, 13 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/error-recovery4.C

Comments

Jason Merrill Sept. 19, 2016, 2:23 p.m. UTC | #1
>        if (tree t = maybe_new_partial_specialization (type))
>         {
> +         if (processing_template_parmlist)
> +           {
> +            /* Some syntactically invalid code can confuse the compiler into
> +               defining a specialization from inside a template parameter
> +               list.  Bail out now so that we won't ICE later.  */
> +             gcc_assert (seen_error ());
> +             return error_mark_node;
> +           }

Rather than decide it's a specialization and then fail, let's avoid
treating it as a specialization in the first place.  I think we can
add a processing_template_parmlist check at the top where we avoid
trying to specialize lambdas.

Jason
diff mbox

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 29d8beb..c1b3d5b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -962,6 +962,14 @@  maybe_process_partial_specialization (tree type)
 
       if (tree t = maybe_new_partial_specialization (type))
 	{
+	  if (processing_template_parmlist)
+	    {
+	     /* Some syntactically invalid code can confuse the compiler into
+		defining a specialization from inside a template parameter
+		list.  Bail out now so that we won't ICE later.  */
+	      gcc_assert (seen_error ());
+	      return error_mark_node;
+	    }
 	  if (!check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (t))
 	      && !at_namespace_scope_p ())
 	    return error_mark_node;
diff --git a/gcc/testsuite/g++.dg/template/error-recovery4.C b/gcc/testsuite/g++.dg/template/error-recovery4.C
new file mode 100644
index 0000000..1725d87
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error-recovery4.C
@@ -0,0 +1,5 @@ 
+// PR c++/77639
+
+template <class, int, class, int> struct B {};
+template <class T, int a, class U struct B<int, 2, char, 1> {}; // { dg-error "" }
+B<int, 2, char, 1> i;