This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PR c++/17805] limit operator overload candidates for enum operands
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 10 Feb 2005 16:22:45 -0200
- Subject: [PR c++/17805] limit operator overload candidates for enum operands
- Organization: Red Hat Global Engineering Services Compiler Team
We're a bit too lenient in creating the candidate list for overload
resolution for expressions that use user-defined operator functions.
This patch arranges for us to reject functions that don't get an exact
match for at least one of the enum-typed arguments, if none of the
arguments have class types.
Regression-tested on x86_64-linux-gnu. Ok to install?
Index: gcc/cp/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
PR c++/17805
* call.c (build_new_op): Filter out operator functions that don't
satisfy enum-conversion match requirements.
Index: gcc/cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.530
diff -u -p -r1.530 call.c
--- gcc/cp/call.c 10 Feb 2005 07:55:04 -0000 1.530
+++ gcc/cp/call.c 10 Feb 2005 17:42:09 -0000
@@ -3656,6 +3656,54 @@ build_new_op (enum tree_code code, int f
TYPE_BINFO (TREE_TYPE (arg1)),
flags, &candidates);
}
+ /* Per 13.3.1.2/3, 2nd bullet, if no operand has a class type, then
+ only non-member functions that have type T1 or reference to
+ cv-qualified-opt T1 for the first argument, if the first argument
+ has an enumeration type, or T2 or reference to cv-qualified-opt
+ T2 for the second argument, if the the second argument has an
+ enumeration type. Filter out those that don't match. */
+ else if (! arg2 || ! CLASS_TYPE_P (TREE_TYPE (arg2)))
+ {
+ struct z_candidate **candp, **next;
+
+ for (candp = &candidates; *candp; candp = next)
+ {
+ tree parmlist, parmtype;
+
+ cand = *candp;
+ next = &cand->next;
+
+ parmlist = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+ parmtype = TREE_VALUE (parmlist);
+
+ if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
+ && (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)),
+ TYPE_MAIN_VARIANT (parmtype))
+ || (TREE_CODE (parmtype) == REFERENCE_TYPE
+ && reference_related_p (TREE_TYPE (arg1),
+ TREE_TYPE (parmtype)))))
+ continue;
+
+ if (! arg2)
+ continue;
+
+ parmlist = TREE_CHAIN (parmlist);
+ parmtype = TREE_VALUE (parmlist);
+
+ if (TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
+ && (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg2)),
+ TYPE_MAIN_VARIANT (parmtype))
+ || (TREE_CODE (parmtype) == REFERENCE_TYPE
+ && reference_related_p (TREE_TYPE (arg2),
+ TREE_TYPE (parmtype)))))
+ continue;
+
+ /* Neither argument has an appropriate type, so remove this
+ candidate function from the list. */
+ *candp = cand->next;
+ next = candp;
+ }
+ }
/* Rearrange the arguments for ?: so that add_builtin_candidate only has
to know about two args; a builtin candidate will always have a first
Index: gcc/testsuite/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
PR c++/17805
* g++.dg/overload/operator2.C: New.
Index: gcc/testsuite/g++.dg/overload/operator2.C
===================================================================
RCS file: gcc/testsuite/g++.dg/overload/operator2.C
diff -N gcc/testsuite/g++.dg/overload/operator2.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/overload/operator2.C 10 Feb 2005 17:42:30 -0000
@@ -0,0 +1,20 @@
+// PR c++/17805
+
+// Per 13.3.1.2/3 bullet 2, an operator function is not a candidate
+// for overload resolution if neither argument is of class type and
+// neither enumerator-typed argument gets an exact match, with or
+// without reference binding, for the corresponding parameter.
+
+// { dg-do compile }
+
+struct A
+{
+ A(int);
+ A(const char*);
+};
+
+bool operator==(const A&, const A&);
+
+enum E { e };
+
+bool b = (e == ""); // { dg-error "no match" }
--
Alexandre Oliva http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}