Patchwork C++ PATCH for c++/55232 (ICE on diagnostic in variadic template function)

login
register
mail settings
Submitter Jason Merrill
Date Feb. 14, 2013, 7:53 p.m.
Message ID <511D40CC.4020304@redhat.com>
Download mbox | patch
Permalink /patch/220489/
State New
Headers show

Comments

Jason Merrill - Feb. 14, 2013, 7:53 p.m.
We try to print typename types when dumping template bindings in order 
to be helpful.  But we can't do that for typenames in pack expansions 
because we don't know which pack element we're interested in.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 91f6181cddda74ddfbae6e57454ab69659847928
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Feb 14 09:13:54 2013 -0500

    	PR c++/55232
    	* error.c (find_typenames_r): Don't walk into a pack expansion.

diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index a4b3320..60119ec 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1283,7 +1283,7 @@  struct find_typenames_t
 };
 
 static tree
-find_typenames_r (tree *tp, int * /*walk_subtrees*/, void *data)
+find_typenames_r (tree *tp, int *walk_subtrees, void *data)
 {
   struct find_typenames_t *d = (struct find_typenames_t *)data;
   tree mv = NULL_TREE;
@@ -1296,6 +1296,14 @@  find_typenames_r (tree *tp, int * /*walk_subtrees*/, void *data)
     /* Add the typename without any cv-qualifiers.  */
     mv = TYPE_MAIN_VARIANT (*tp);
 
+  if (TREE_CODE (*tp) == TYPE_PACK_EXPANSION)
+    {
+      /* Don't mess with parameter packs since we don't remember
+	 the pack expansion context for a particular typename.  */
+      *walk_subtrees = false;
+      return NULL_TREE;
+    }
+
   if (mv && (mv == *tp || !pointer_set_insert (d->p_set, mv)))
     vec_safe_push (d->typenames, mv);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-diag1.C b/gcc/testsuite/g++.dg/cpp0x/variadic-diag1.C
new file mode 100644
index 0000000..53182d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-diag1.C
@@ -0,0 +1,22 @@ 
+// PR c++/55232
+// { dg-do compile { target c++11 } }
+
+struct vector
+{
+    typedef int value_type;
+};
+
+template< class U, class... T >
+struct X
+{
+    void push_back( typename T::value_type ... vals )
+    {
+      U::asoeuth;		// { dg-error "" }
+    }
+};
+
+int main()
+{
+  X< int, vector > x;
+  x.push_back( 0 );
+}