Commit 4cff6abe by Nathan Sidwell Committed by Nathan Sidwell

call.c (build_conv): Typo in comment.

cp:
	* call.c (build_conv): Typo in comment.
	(add_builtin_candidate): Add more explanation.
	Remove extra test for ENUMERAL_TYPE in {PRE,POST}INCREMENT_EXPR.
	Allow ENUMERAL_TYPEs for relops and eqops. Add both candidates
	when we have enumeral types.
	(add_builtin_candidates): Add more explanation. Add ENUMERAL_TYPE
	candidates for relops and eqops.
	(joust): Simplify control flow. Allow a non-template user
	function to hide a builtin.
testsuite:
	* g++.old-deja/g++.pt/overload14.C: New test.

From-SVN: r39197
parent 20b11783
2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
* call.c (build_conv): Typo in comment.
(add_builtin_candidate): Add more explanation.
Remove extra test for ENUMERAL_TYPE in {PRE,POST}INCREMENT_EXPR.
Allow ENUMERAL_TYPEs for relops and eqops. Add both candidates
when we have enumeral types.
(add_builtin_candidates): Add more explanation. Add ENUMERAL_TYPE
candidates for relops and eqops.
(joust): Simplify control flow. Allow a non-template user
function to hide a builtin.
2001-01-22 Nathan Sidwell <nathan@codesourcery.com> 2001-01-22 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (unification_kind_t): Add DEDUCE_ORDER. * cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
......
...@@ -608,7 +608,7 @@ build_conv (code, type, from) ...@@ -608,7 +608,7 @@ build_conv (code, type, from)
tree t; tree t;
int rank = ICS_STD_RANK (from); int rank = ICS_STD_RANK (from);
/* We can't use buidl1 here because CODE could be USER_CONV, which /* We can't use buildl1 here because CODE could be USER_CONV, which
takes two arguments. In that case, the caller is responsible for takes two arguments. In that case, the caller is responsible for
filling in the second argument. */ filling in the second argument. */
t = make_node (code); t = make_node (code);
...@@ -1563,7 +1563,12 @@ promoted_arithmetic_type_p (type) ...@@ -1563,7 +1563,12 @@ promoted_arithmetic_type_p (type)
/* Create any builtin operator overload candidates for the operator in /* Create any builtin operator overload candidates for the operator in
question given the converted operand types TYPE1 and TYPE2. The other question given the converted operand types TYPE1 and TYPE2. The other
args are passed through from add_builtin_candidates to args are passed through from add_builtin_candidates to
build_builtin_candidate. */ build_builtin_candidate.
TYPE1 and TYPE2 may not be permissible, and we must filter them.
If CODE is requires candidates operands of the same type of the kind
of which TYPE1 and TYPE2 are, we add both candidates
CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */
static struct z_candidate * static struct z_candidate *
add_builtin_candidate (candidates, code, code2, fnname, type1, type2, add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
...@@ -1611,8 +1616,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2, ...@@ -1611,8 +1616,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
return candidates; return candidates;
case POSTINCREMENT_EXPR: case POSTINCREMENT_EXPR:
case PREINCREMENT_EXPR: case PREINCREMENT_EXPR:
if ((ARITHMETIC_TYPE_P (type1) && TREE_CODE (type1) != ENUMERAL_TYPE) if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1))
|| TYPE_PTROB_P (type1))
{ {
type1 = build_reference_type (type1); type1 = build_reference_type (type1);
break; break;
...@@ -1712,8 +1716,8 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2, ...@@ -1712,8 +1716,8 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
candidate operator functions of the form112) candidate operator functions of the form112)
ptrdiff_t operator-(T, T); ptrdiff_t operator-(T, T);
16For every pointer type T, there exist candidate operator functions of 16For every enumeral or pointer type T, there exist candidate operator
the form functions of the form
bool operator<(T, T); bool operator<(T, T);
bool operator>(T, T); bool operator>(T, T);
bool operator<=(T, T); bool operator<=(T, T);
...@@ -1757,14 +1761,18 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2, ...@@ -1757,14 +1761,18 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
type1 = type2; type1 = type2;
break; break;
} }
/* FALLTHROUGH */
case LT_EXPR: case LT_EXPR:
case GT_EXPR: case GT_EXPR:
case LE_EXPR: case LE_EXPR:
case GE_EXPR: case GE_EXPR:
case MAX_EXPR: case MAX_EXPR:
case MIN_EXPR: case MIN_EXPR:
if ((ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
|| (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))) break;
if (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
break;
if (TREE_CODE (type1) == ENUMERAL_TYPE && TREE_CODE (type2) == ENUMERAL_TYPE)
break; break;
if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1])) if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1]))
{ {
...@@ -1940,15 +1948,16 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2, ...@@ -1940,15 +1948,16 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
my_friendly_abort (367); my_friendly_abort (367);
} }
/* If we're dealing with two pointer types, we need candidates /* If we're dealing with two pointer types or two enumeral types,
for both of them. */ we need candidates for both of them. */
if (type2 && !same_type_p (type1, type2) if (type2 && !same_type_p (type1, type2)
&& TREE_CODE (type1) == TREE_CODE (type2) && TREE_CODE (type1) == TREE_CODE (type2)
&& (TREE_CODE (type1) == REFERENCE_TYPE && (TREE_CODE (type1) == REFERENCE_TYPE
|| (TREE_CODE (type1) == POINTER_TYPE || (TREE_CODE (type1) == POINTER_TYPE
&& TYPE_PTRMEM_P (type1) == TYPE_PTRMEM_P (type2)) && TYPE_PTRMEM_P (type1) == TYPE_PTRMEM_P (type2))
|| TYPE_PTRMEMFUNC_P (type1) || TYPE_PTRMEMFUNC_P (type1)
|| IS_AGGR_TYPE (type1))) || IS_AGGR_TYPE (type1)
|| TREE_CODE (type1) == ENUMERAL_TYPE))
{ {
candidates = build_builtin_candidate candidates = build_builtin_candidate
(candidates, fnname, type1, type1, args, argtypes, flags); (candidates, fnname, type1, type1, args, argtypes, flags);
...@@ -1977,7 +1986,12 @@ type_decays_to (type) ...@@ -1977,7 +1986,12 @@ type_decays_to (type)
2) pointer-pair taking candidates. These are generated for each type 2) pointer-pair taking candidates. These are generated for each type
one of the input types converts to. one of the input types converts to.
3) arithmetic candidates. According to the standard, we should generate 3) arithmetic candidates. According to the standard, we should generate
all of these, but I'm trying not to... */ all of these, but I'm trying not to...
Here we generate a superset of the possible candidates for this particular
case. That is a subset of the full set the standard defines, plus some
other cases which the standard disallows. add_builtin_candidate will
filter out the illegal set. */
static struct z_candidate * static struct z_candidate *
add_builtin_candidates (candidates, code, code2, fnname, args, flags) add_builtin_candidates (candidates, code, code2, fnname, args, flags)
...@@ -1987,6 +2001,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags) ...@@ -1987,6 +2001,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
int flags; int flags;
{ {
int ref1, i; int ref1, i;
int enum_p = 0;
tree type, argtypes[3]; tree type, argtypes[3];
/* TYPES[i] is the set of possible builtin-operator parameter types /* TYPES[i] is the set of possible builtin-operator parameter types
we will consider for the Ith argument. These are represented as we will consider for the Ith argument. These are represented as
...@@ -2038,6 +2053,16 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags) ...@@ -2038,6 +2053,16 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
case COMPONENT_REF: case COMPONENT_REF:
return candidates; return candidates;
case COND_EXPR:
case EQ_EXPR:
case NE_EXPR:
case LT_EXPR:
case LE_EXPR:
case GT_EXPR:
case GE_EXPR:
enum_p = 1;
/* FALLTHROUGH */
default: default:
ref1 = 0; ref1 = 0;
} }
...@@ -2086,7 +2111,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags) ...@@ -2086,7 +2111,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
if (i != 0 || ! ref1) if (i != 0 || ! ref1)
{ {
type = TYPE_MAIN_VARIANT (type_decays_to (type)); type = TYPE_MAIN_VARIANT (type_decays_to (type));
if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE) if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
types[i] = tree_cons (NULL_TREE, type, types[i]); types[i] = tree_cons (NULL_TREE, type, types[i]);
if (INTEGRAL_TYPE_P (type)) if (INTEGRAL_TYPE_P (type))
type = type_promotes_to (type); type = type_promotes_to (type);
...@@ -2105,7 +2130,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags) ...@@ -2105,7 +2130,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
if (i != 0 || ! ref1) if (i != 0 || ! ref1)
{ {
type = TYPE_MAIN_VARIANT (type_decays_to (type)); type = TYPE_MAIN_VARIANT (type_decays_to (type));
if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE) if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
types[i] = tree_cons (NULL_TREE, type, types[i]); types[i] = tree_cons (NULL_TREE, type, types[i]);
if (INTEGRAL_TYPE_P (type)) if (INTEGRAL_TYPE_P (type))
type = type_promotes_to (type); type = type_promotes_to (type);
...@@ -5186,20 +5211,33 @@ joust (cand1, cand2, warn) ...@@ -5186,20 +5211,33 @@ joust (cand1, cand2, warn)
if (winner) if (winner)
return winner; return winner;
/* or, if not that, /* or, if not that, a non-template function is better than a
F1 is a non-template function and F2 is a template function */ template function. */
if (! cand1->template && cand2->template) if (! cand1->template && cand2->template)
return 1; return 1;
else if (cand1->template && ! cand2->template) else if (cand1->template && ! cand2->template)
return -1; return -1;
else if (cand1->template && cand2->template) else if (cand1->template && cand2->template)
{
winner = more_specialized winner = more_specialized
(TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template), (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
DEDUCE_ORDER, DEDUCE_ORDER,
/* Never do unification on the 'this' parameter. */ /* Never do unification on the 'this' parameter. */
TREE_VEC_LENGTH (cand1->convs) TREE_VEC_LENGTH (cand1->convs)
- DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn)); - DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn));
if (winner)
return winner;
}
/* or, if not that, a non-template user function is better than a
builtin. */
if (TREE_CODE (cand1->fn) != IDENTIFIER_NODE
&& TREE_CODE (cand2->fn) == IDENTIFIER_NODE)
return 1;
else if (TREE_CODE (cand1->fn) == IDENTIFIER_NODE
&& TREE_CODE (cand2->fn) != IDENTIFIER_NODE)
return -1;
/* or, if not that, /* or, if not that,
the context is an initialization by user-defined conversion (see the context is an initialization by user-defined conversion (see
...@@ -5209,11 +5247,15 @@ joust (cand1, cand2, warn) ...@@ -5209,11 +5247,15 @@ joust (cand1, cand2, warn)
sequence than the standard conversion sequence from the return type sequence than the standard conversion sequence from the return type
of F2 to the destination type. */ of F2 to the destination type. */
if (! winner && cand1->second_conv) if (cand1->second_conv)
{
winner = compare_ics (cand1->second_conv, cand2->second_conv); winner = compare_ics (cand1->second_conv, cand2->second_conv);
if (winner)
return winner;
}
/* If the built-in candidates are the same, arbitrarily pick one. */ /* If the built-in candidates are the same, arbitrarily pick one. */
if (! winner && cand1->fn == cand2->fn if (cand1->fn == cand2->fn
&& TREE_CODE (cand1->fn) == IDENTIFIER_NODE) && TREE_CODE (cand1->fn) == IDENTIFIER_NODE)
{ {
for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
...@@ -5253,7 +5295,7 @@ tweak: ...@@ -5253,7 +5295,7 @@ tweak:
/* Extension: If the worst conversion for one candidate is worse than the /* Extension: If the worst conversion for one candidate is worse than the
worst conversion for the other, take the first. */ worst conversion for the other, take the first. */
if (! winner && ! pedantic) if (!pedantic)
{ {
int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK; int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK;
...@@ -5271,7 +5313,8 @@ tweak: ...@@ -5271,7 +5313,8 @@ tweak:
return -1; return -1;
} }
return winner; my_friendly_assert (!winner, 20010121);
return 0;
} }
/* Given a list of candidates for overloading, find the best one, if any. /* Given a list of candidates for overloading, find the best one, if any.
......
2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.pt/overload14.C: New test.
2001-01-22 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> 2001-01-22 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* gcc.c-torture/execute/20010122-1.c: New test, exercise * gcc.c-torture/execute/20010122-1.c: New test, exercise
......
// Build don't link:
//
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 18 Jan 2001 <nathan@codesourcery.com>
// Bug 1639. We failed to have builtin relop candidates with enumeral type.
template <typename T1, typename T2> void operator == (T1, T2);
enum E {e1};
void operator != (E, E);
bool Foo (E e)
{
return e == e1;
}
bool Baz (E e)
{
return e != e1; // ERROR - void not ignored.
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment