Message ID | 20160711201552.GT7387@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
OK. On Mon, Jul 11, 2016 at 4:15 PM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > add_conv_candidate creates cand->fn which is not a FUNCTION_DECL, but > some type, all spots in convert_like_real assume that if fn is non-NULL, it > is some decl. Just a couple of lines above this hunk we even have a comment > reminding us on cand->fn not having to be a decl: > /* Since cand->fn will be a type, not a function, for a conversion > function, we must be careful not to unconditionally look at > DECL_NAME here. */ > So, this patch uses just convert_like instead of convert_like_with_context > if cand->fn is not a decl (or shall I test for TREE_CODE (cand->fn) == > FUNCTION_DECL instead?). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/6.2? > > 2016-07-11 Jakub Jelinek <jakub@redhat.com> > > PR c++/71835 > * call.c (build_op_call_1): Use convert_like_with_context only > if cand->fn is a decl. > > * g++.dg/conversion/ambig3.C: New test. > > --- gcc/cp/call.c.jj 2016-07-11 11:14:28.000000000 +0200 > +++ gcc/cp/call.c 2016-07-11 14:42:44.466186449 +0200 > @@ -4406,8 +4406,11 @@ build_op_call_1 (tree obj, vec<tree, va_ > result = build_over_call (cand, LOOKUP_NORMAL, complain); > else > { > - obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1, > - complain); > + if (DECL_P (cand->fn)) > + obj = convert_like_with_context (cand->convs[0], obj, cand->fn, > + -1, complain); > + else > + obj = convert_like (cand->convs[0], obj, complain); > obj = convert_from_reference (obj); > result = cp_build_function_call_vec (obj, args, complain); > } > --- gcc/testsuite/g++.dg/conversion/ambig3.C.jj 2016-07-11 14:47:26.668826075 +0200 > +++ gcc/testsuite/g++.dg/conversion/ambig3.C 2016-07-11 14:46:49.000000000 +0200 > @@ -0,0 +1,13 @@ > +// PR c++/71835 > +// { dg-do compile } > + > +typedef void T (int); > +struct A { operator T * (); }; // { dg-message "candidate" } > +struct B { operator T * (); }; // { dg-message "candidate" } > +struct C : A, B {} c; > + > +void > +foo () > +{ > + c (0); // { dg-error "is ambiguous" } > +} > > Jakub
--- gcc/cp/call.c.jj 2016-07-11 11:14:28.000000000 +0200 +++ gcc/cp/call.c 2016-07-11 14:42:44.466186449 +0200 @@ -4406,8 +4406,11 @@ build_op_call_1 (tree obj, vec<tree, va_ result = build_over_call (cand, LOOKUP_NORMAL, complain); else { - obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1, - complain); + if (DECL_P (cand->fn)) + obj = convert_like_with_context (cand->convs[0], obj, cand->fn, + -1, complain); + else + obj = convert_like (cand->convs[0], obj, complain); obj = convert_from_reference (obj); result = cp_build_function_call_vec (obj, args, complain); } --- gcc/testsuite/g++.dg/conversion/ambig3.C.jj 2016-07-11 14:47:26.668826075 +0200 +++ gcc/testsuite/g++.dg/conversion/ambig3.C 2016-07-11 14:46:49.000000000 +0200 @@ -0,0 +1,13 @@ +// PR c++/71835 +// { dg-do compile } + +typedef void T (int); +struct A { operator T * (); }; // { dg-message "candidate" } +struct B { operator T * (); }; // { dg-message "candidate" } +struct C : A, B {} c; + +void +foo () +{ + c (0); // { dg-error "is ambiguous" } +}