aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-05-12 13:34:28 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-05-12 13:34:28 -0400
commit404f08f8d52a28a0590e858c339c68ca7f78ccfd (patch)
tree6f028aa195e1257bca4a73bcbc7579f2af2613ab /gcc
parent5c824000a5b855d454483bee7d32850f161ecdab (diff)
downloadgcc-404f08f8d52a28a0590e858c339c68ca7f78ccfd.zip
gcc-404f08f8d52a28a0590e858c339c68ca7f78ccfd.tar.gz
gcc-404f08f8d52a28a0590e858c339c68ca7f78ccfd.tar.bz2
call.c (add_candidates): Distinguish between type(x) and x.operator type().
* 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. From-SVN: r159333
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c15
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/conversion/op1.C2
-rw-r--r--gcc/testsuite/g++.dg/template/conv11.C10
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" }
+}