re PR c++/17805 (too liberal operator lookup)
/cp 2012-10-15 Alexandre Oliva <aoliva@redhat.com> Paolo Carlini <paolo.carlini@oracle.com> PR c++/17805 * call.c (build_new_op): Filter out operator functions that don't satisfy enum-conversion match requirements. /testsuite 2012-10-15 Alexandre Oliva <aoliva@redhat.com> Paolo Carlini <paolo.carlini@oracle.com> PR c++/17805 * g++.dg/overload/operator6.C: New. Co-Authored-By: Paolo Carlini <paolo.carlini@oracle.com> From-SVN: r192471
This commit is contained in:
parent
c9e3b2097b
commit
52243905a2
4 changed files with 87 additions and 3 deletions
|
@ -1,3 +1,10 @@
|
|||
2012-10-15 Alexandre Oliva <aoliva@redhat.com>
|
||||
Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/17805
|
||||
* call.c (build_new_op): Filter out operator functions that don't
|
||||
satisfy enum-conversion match requirements.
|
||||
|
||||
2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/50080 (again)
|
||||
|
|
|
@ -5043,6 +5043,11 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
|
|||
NULL_TREE, arglist, NULL_TREE,
|
||||
NULL_TREE, false, NULL_TREE, NULL_TREE,
|
||||
flags, &candidates, complain);
|
||||
|
||||
args[0] = arg1;
|
||||
args[1] = arg2;
|
||||
args[2] = NULL_TREE;
|
||||
|
||||
/* Add class-member operators to the candidate set. */
|
||||
if (CLASS_TYPE_P (TREE_TYPE (arg1)))
|
||||
{
|
||||
|
@ -5062,10 +5067,49 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
|
|||
BASELINK_ACCESS_BINFO (fns),
|
||||
flags, &candidates, complain);
|
||||
}
|
||||
/* 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;
|
||||
|
||||
args[0] = arg1;
|
||||
args[1] = arg2;
|
||||
args[2] = NULL_TREE;
|
||||
for (candp = &candidates; *candp; candp = next)
|
||||
{
|
||||
tree parmlist, parmtype;
|
||||
int i, nargs = (arg2 ? 2 : 1);
|
||||
|
||||
cand = *candp;
|
||||
next = &cand->next;
|
||||
|
||||
parmlist = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
|
||||
|
||||
for (i = 0; i < nargs; ++i)
|
||||
{
|
||||
parmtype = TREE_VALUE (parmlist);
|
||||
|
||||
if (TREE_CODE (parmtype) == REFERENCE_TYPE)
|
||||
parmtype = TREE_TYPE (parmtype);
|
||||
if (TREE_CODE (TREE_TYPE (args[i])) == ENUMERAL_TYPE
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (args[i]), parmtype)))
|
||||
break;
|
||||
|
||||
parmlist = TREE_CHAIN (parmlist);
|
||||
}
|
||||
|
||||
/* No argument has an appropriate type, so remove this
|
||||
candidate function from the list. */
|
||||
if (i == nargs)
|
||||
{
|
||||
*candp = cand->next;
|
||||
next = candp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_builtin_candidates (&candidates, code, code2, fnname, args,
|
||||
flags, complain);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2012-10-15 Alexandre Oliva <aoliva@redhat.com>
|
||||
Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/17805
|
||||
* g++.dg/overload/operator6.C: New.
|
||||
|
||||
2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/50080 (again)
|
||||
|
|
27
gcc/testsuite/g++.dg/overload/operator6.C
Normal file
27
gcc/testsuite/g++.dg/overload/operator6.C
Normal file
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
struct A
|
||||
{
|
||||
A(int);
|
||||
A(const char*);
|
||||
};
|
||||
|
||||
bool operator==(const A&, const A&);
|
||||
const A& operator*(const A&);
|
||||
|
||||
enum E { e };
|
||||
|
||||
bool b1 = (e == ""); // { dg-error "no match" }
|
||||
|
||||
bool b2 = (A(1) == "");
|
||||
|
||||
bool b3 = (e == A(1));
|
||||
|
||||
const A& a1 = *e; // { dg-error "no match" }
|
||||
|
||||
const A& a2 = *A(1);
|
Loading…
Add table
Reference in a new issue