diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/call.c | 15 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/op1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/conv11.C | 10 |
6 files changed, 35 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5c8ff3a..3872df2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2010-05-12 Jason Merrill <jason@redhat.com> + * 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 17ad99e..204a6bb 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 0528289..df961e0 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 6425c9e..a431f8a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-05-12 Jason Merrill <jason@redhat.com> + * 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 <hongjiu.lu@intel.com> diff --git a/gcc/testsuite/g++.dg/conversion/op1.C b/gcc/testsuite/g++.dg/conversion/op1.C index 3aa21c7..990cdaa 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 0000000..846b852 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv11.C @@ -0,0 +1,10 @@ +int i; +struct A +{ + template <class T> operator T&() { return i; } +}; + +int main() +{ + A().operator int(); // { dg-error "operator int" } +} |