Patchwork C++ PATCH for c++/45236

login
register
mail settings
Submitter Jason Merrill
Date Aug. 9, 2010, 9:12 p.m.
Message ID <4C606F52.7060200@redhat.com>
Download mbox | patch
Permalink /patch/61320/
State New
Headers show

Comments

Jason Merrill - Aug. 9, 2010, 9:12 p.m.
In this testcase, adjusting the template arguments for the nested class 
template failed because we were trying to adjust the arguments for the 
enclosing class template again and failing.  This is unnecessary; we 
already have the adjusted arguments from when we looked up the member 
template.  So this patch just reuses any enclosing arguments.

To improve compiler speed for template-heavy code, we ought to look more 
at avoiding redundant use of coerce_template_args like this; after I 
switched specialization lookup to use hash tables, coercion was at the 
top of the profile, with about 16% of compile time.

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

Patch

commit 7cf59ddcccb7809fa17ef1619d44adc85ab8000e
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Aug 9 16:08:59 2010 -0400

    	PR c++/45236
    	* pt.c (lookup_template_class): Don't re-coerce outer parms.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bb6b1a0..02c54f9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6540,11 +6540,16 @@  lookup_template_class (tree d1,
 	       i > 0 && t != NULL_TREE;
 	       --i, t = TREE_CHAIN (t))
 	    {
-	      tree a = coerce_template_parms (TREE_VALUE (t),
-					      arglist, gen_tmpl,
-					      complain,
-					      /*require_all_args=*/true,
-					      /*use_default_args=*/true);
+	      tree a;
+	      if (i == saved_depth)
+		a = coerce_template_parms (TREE_VALUE (t),
+					   arglist, gen_tmpl,
+					   complain,
+					   /*require_all_args=*/true,
+					   /*use_default_args=*/true);
+	      else
+		/* Outer levels should have already been coerced.  */
+		a = TMPL_ARGS_LEVEL (arglist, i);
 
 	      /* Don't process further if one of the levels fails.  */
 	      if (a == error_mark_node)
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-104.C b/gcc/testsuite/g++.dg/cpp0x/variadic-104.C
new file mode 100644
index 0000000..c693b33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-104.C
@@ -0,0 +1,16 @@ 
+// PR c++/45236
+// { dg-options -std=c++0x }
+
+template <class T, class S> class foo;
+
+template<template<int...> class C, int... II, class S>
+struct foo<C<II...>,S>
+{
+    template <class U>
+    struct bar { typedef int type; };
+};
+
+template <int... I>
+struct A {};
+
+foo<A<3>, float>::bar<int> x;