From patchwork Tue Sep 4 18:48:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for c++/54437 (firefox build failure) Date: Tue, 04 Sep 2012 08:48:01 -0000 From: Jason Merrill X-Patchwork-Id: 181653 Message-Id: <50464CE1.4090904@redhat.com> To: gcc-patches List Here, the problem was that we were resolving the address of an overloaded function in the context of the template being called (which doesn't have access to the function) rather than the caller (which does). We need to massage explicit template arguments before we enter the callee's context. Tested x86_64-pc-linux-gnu, applying to trunk. commit c17767b10d05c0ea47107a3b7f067da76cc5ad8d Author: Jason Merrill Date: Tue Sep 4 11:27:03 2012 -0400 PR c++/54437 PR c++/51213 * pt.c (fn_type_unification): Call coerce_template_parms before entering substitution context. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4a39427..6f6235c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14591,11 +14591,22 @@ fn_type_unification (tree fn, static int deduction_depth; struct pending_template *old_last_pend = last_pending_template; struct tinst_level *old_error_tinst = last_error_tinst_level; + tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (fn); tree tinst; tree r = error_mark_node; - if (excessive_deduction_depth) - return error_mark_node; + /* Adjust any explicit template arguments before entering the + substitution context. */ + if (explicit_targs) + { + explicit_targs + = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, + complain, + /*require_all_args=*/false, + /*use_default_args=*/false)); + if (explicit_targs == error_mark_node) + return error_mark_node; + } /* In C++0x, it's possible to have a function template whose type depends on itself recursively. This is most obvious with decltype, but can also @@ -14608,6 +14619,8 @@ fn_type_unification (tree fn, substitutions back up to the initial one. This is, of course, not reentrant. */ + if (excessive_deduction_depth) + return error_mark_node; tinst = build_tree_list (fn, targs); if (!push_tinst_level (tinst)) { @@ -14640,23 +14653,10 @@ fn_type_unification (tree fn, specified template argument values. If a substitution in a template parameter or in the function type of the function template results in an invalid type, type deduction fails. */ - tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (fn); int i, len = TREE_VEC_LENGTH (tparms); location_t loc = input_location; - tree converted_args; bool incomplete = false; - if (explicit_targs == error_mark_node) - goto fail; - - converted_args - = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, - complain, - /*require_all_args=*/false, - /*use_default_args=*/false)); - if (converted_args == error_mark_node) - goto fail; - /* Substitute the explicit args into the function type. This is necessary so that, for instance, explicitly declared function arguments can match null pointed constants. If we were given @@ -14667,7 +14667,7 @@ fn_type_unification (tree fn, { tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); bool parameter_pack = false; - tree targ = TREE_VEC_ELT (converted_args, i); + tree targ = TREE_VEC_ELT (explicit_targs, i); /* Dig out the actual parm. */ if (TREE_CODE (parm) == TYPE_DECL @@ -14705,7 +14705,7 @@ fn_type_unification (tree fn, processing_template_decl += incomplete; input_location = DECL_SOURCE_LOCATION (fn); - fntype = tsubst (TREE_TYPE (fn), converted_args, + fntype = tsubst (TREE_TYPE (fn), explicit_targs, complain | tf_partial, NULL_TREE); input_location = loc; processing_template_decl -= incomplete; @@ -14714,8 +14714,8 @@ fn_type_unification (tree fn, goto fail; /* Place the explicitly specified arguments in TARGS. */ - for (i = NUM_TMPL_ARGS (converted_args); i--;) - TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i); + for (i = NUM_TMPL_ARGS (explicit_targs); i--;) + TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i); } /* Never do unification on the 'this' parameter. */ diff --git a/gcc/testsuite/g++.dg/template/access24.C b/gcc/testsuite/g++.dg/template/access24.C new file mode 100644 index 0000000..9f19226 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access24.C @@ -0,0 +1,8 @@ +// PR c++/54437 + +template void f(); +class A { + template static void g(); + template static void h () { f >(); } + static void i() { h(); } +};