diff options
author | Jason Merrill <jason@redhat.com> | 2015-10-22 20:51:14 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-10-22 20:51:14 -0400 |
commit | ba2b189e848df411a6e100824b8596d2dc84d84b (patch) | |
tree | c9a4ea95262666890d67b0f92815b36bb9255da5 | |
parent | d4db50606926a56219b6952cd84d4f0880d12799 (diff) | |
download | gcc-ba2b189e848df411a6e100824b8596d2dc84d84b.zip gcc-ba2b189e848df411a6e100824b8596d2dc84d84b.tar.gz gcc-ba2b189e848df411a6e100824b8596d2dc84d84b.tar.bz2 |
call.c (add_template_conv_candidate): Pass DEDUCE_CALL.
* call.c (add_template_conv_candidate): Pass DEDUCE_CALL.
(add_template_candidate_real): Handle it.
(fn_type_unification): Handle it.
From-SVN: r229210
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/call.c | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/conv-tmpl1.C | 15 |
4 files changed, 40 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 05ffbdc..e2fd161 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2015-10-22 Jason Merrill <jason@redhat.com> + * call.c (add_template_conv_candidate): Pass DEDUCE_CALL. + (add_template_candidate_real): Handle it. + (fn_type_unification): Handle it. + * call.c (add_conv_candidate): Remove first_arg parm. (add_template_conv_candidate): Likewise. (add_template_candidate_real): Don't pass it. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 9304aac..5b57dc9 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3027,6 +3027,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, { if (first_arg_without_in_chrg != NULL_TREE) first_arg_without_in_chrg = NULL_TREE; + else if (return_type && strict == DEDUCE_CALL) + /* We're deducing for a call to the result of a template conversion + function, so the args don't contain 'this'; leave them alone. */; else ++skip_without_in_chrg; } @@ -3167,6 +3170,11 @@ add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype, flags, NULL_TREE, strict, complain); } +/* Create an overload candidate for the conversion function template TMPL, + returning RETURN_TYPE, which will be invoked for expression OBJ to produce a + pointer-to-function which will in turn be called with the argument list + ARGLIST, and add it to CANDIDATES. This does not change ARGLIST. FLAGS is + passed on to implicit_conversion. */ static struct z_candidate * add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, @@ -3178,7 +3186,7 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, return add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE, NULL_TREE, arglist, return_type, access_path, - conversion_path, 0, obj, DEDUCE_CONV, + conversion_path, 0, obj, DEDUCE_CALL, complain); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 142245a..ffe02da 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17235,7 +17235,9 @@ pack_deducible_p (tree parm, tree fn) DEDUCE_CALL: We are deducing arguments for a function call, as in - [temp.deduct.call]. + [temp.deduct.call]. If RETURN_TYPE is non-null, we are + deducing arguments for a call to the result of a conversion + function template, as in [over.call.object]. DEDUCE_CONV: We are deducing arguments for a conversion function, as in @@ -17402,7 +17404,15 @@ fn_type_unification (tree fn, /* Never do unification on the 'this' parameter. */ parms = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (fntype)); - if (return_type) + if (return_type && strict == DEDUCE_CALL) + { + /* We're deducing for a call to the result of a template conversion + function. The parms we really want are in return_type. */ + if (POINTER_TYPE_P (return_type)) + return_type = TREE_TYPE (return_type); + parms = TYPE_ARG_TYPES (return_type); + } + else if (return_type) { tree *new_args; diff --git a/gcc/testsuite/g++.dg/cpp0x/conv-tmpl1.C b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl1.C new file mode 100644 index 0000000..7f866da --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl1.C @@ -0,0 +1,15 @@ +// { dg-do compile { target c++11 } } + +template <class T> +using Fn = void (*)(T); + +struct A +{ + template <class T> + operator Fn<T>(); +}; + +int main() +{ + A()(42); +} |