From: jason Date: Wed, 12 May 2010 17:34:28 +0000 (+0000) Subject: * call.c (add_candidates): Distinguish between type(x) and X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6420cb4a8efa577d63711077742ef0fdf62d2247;p=thirdparty%2Fgcc.git * call.c (add_candidates): Distinguish between type(x) and x.operator type(). (convert_class_to_reference): Set LOOKUP_NO_CONVERSION. (build_new_method_call): Give better error for conversion op. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159333 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5c8ff3a739a0..3872df21d16c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2010-05-12 Jason Merrill + * call.c (add_candidates): Distinguish between type(x) and + x.operator type(). + (convert_class_to_reference): Set LOOKUP_NO_CONVERSION. + (build_new_method_call): Give better error for conversion op. + * call.c (add_candidates): Add first_arg and return_type parms. Add special constructor/conversion op handling. (convert_class_to_reference): Use it. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 17ad99e84267..204a6bbcfc13 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1053,6 +1053,10 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) t = TREE_TYPE (reference_type); + /* We're performing a user-defined conversion to a desired type, so set + this for the benefit of add_candidates. */ + flags |= LOOKUP_NO_CONVERSION; + for (; conversions; conversions = TREE_CHAIN (conversions)) { tree fns = TREE_VALUE (conversions); @@ -4017,7 +4021,12 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args, if (DECL_CONV_FN_P (fn)) { check_converting = !!(flags & LOOKUP_ONLYCONVERTING); - strict = DEDUCE_CONV; + if (flags & LOOKUP_NO_CONVERSION) + /* We're doing return_type(x). */ + strict = DEDUCE_CONV; + else + /* We're doing x.operator return_type(). */ + strict = DEDUCE_EXACT; /* [over.match.funcs] For conversion functions, the function is considered to be a member of the class of the implicit object argument for the purpose of defining the type of @@ -6318,6 +6327,10 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, { if (!COMPLETE_TYPE_P (basetype)) cxx_incomplete_type_error (instance_ptr, basetype); + else if (optype) + error ("no matching function for call to %<%T::operator %T(%A)%#V%>", + basetype, optype, build_tree_list_vec (user_args), + TREE_TYPE (TREE_TYPE (instance_ptr))); else { char *pretty_name; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 052828945804..df961e04856f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4109,8 +4109,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; have already generated a temporary, such as reference initialization and the catch parameter. */ #define DIRECT_BIND (1 << 4) -/* User-defined conversions are not permitted. (Built-in conversions - are permitted.) */ +/* We're performing a user-defined conversion, so more user-defined + conversions are not permitted (only built-in conversions). */ #define LOOKUP_NO_CONVERSION (1 << 5) /* The user has explicitly called a destructor. (Therefore, we do not need to check that the object is non-NULL before calling the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6425c9ecdbfb..a431f8af5033 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-05-12 Jason Merrill + * g++.dg/template/conv11.C: New. + * g++.dg/conversion/op1.C: Adjust expected error. + * g++.old-deja/g++.robertl/eb43.C: Prune "candidates" messages. 2010-05-12 H.J. Lu diff --git a/gcc/testsuite/g++.dg/conversion/op1.C b/gcc/testsuite/g++.dg/conversion/op1.C index 3aa21c7780ef..990cdaa093b7 100644 --- a/gcc/testsuite/g++.dg/conversion/op1.C +++ b/gcc/testsuite/g++.dg/conversion/op1.C @@ -6,5 +6,5 @@ class C int fn (C c) { - return C::operator float(c); // { dg-error "operator U" } + return C::operator float(c); // { dg-error "operator float.C" } } diff --git a/gcc/testsuite/g++.dg/template/conv11.C b/gcc/testsuite/g++.dg/template/conv11.C new file mode 100644 index 000000000000..846b852f493e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv11.C @@ -0,0 +1,10 @@ +int i; +struct A +{ + template operator T&() { return i; } +}; + +int main() +{ + A().operator int(); // { dg-error "operator int" } +}