aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-01-23 10:36:26 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-01-23 10:36:26 +0000
commit4cff6abe405f4e4d660ab6f6cf8b29ba9d49d4fd (patch)
tree633beaf84c5f866061ba3e83160fdcc3d1166a9d /gcc
parent20b11783a374a792e0737b9495bdae63269b5883 (diff)
downloadgcc-4cff6abe405f4e4d660ab6f6cf8b29ba9d49d4fd.zip
gcc-4cff6abe405f4e4d660ab6f6cf8b29ba9d49d4fd.tar.gz
gcc-4cff6abe405f4e4d660ab6f6cf8b29ba9d49d4fd.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/call.c103
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/overload14.C20
4 files changed, 109 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3374dd2..f5b46ff 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+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>
* cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index fa5a508..793a778 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -608,7 +608,7 @@ build_conv (code, type, from)
tree t;
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
filling in the second argument. */
t = make_node (code);
@@ -1563,7 +1563,12 @@ promoted_arithmetic_type_p (type)
/* Create any builtin operator overload candidates for the operator in
question given the converted operand types TYPE1 and TYPE2. The other
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 *
add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
@@ -1611,8 +1616,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
return candidates;
case POSTINCREMENT_EXPR:
case PREINCREMENT_EXPR:
- if ((ARITHMETIC_TYPE_P (type1) && TREE_CODE (type1) != ENUMERAL_TYPE)
- || TYPE_PTROB_P (type1))
+ if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1))
{
type1 = build_reference_type (type1);
break;
@@ -1712,8 +1716,8 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
candidate operator functions of the form112)
ptrdiff_t operator-(T, T);
- 16For every pointer type T, there exist candidate operator functions of
- the form
+ 16For every enumeral or pointer type T, there exist candidate operator
+ functions of the form
bool operator<(T, T);
bool operator>(T, T);
bool operator<=(T, T);
@@ -1757,15 +1761,19 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
type1 = type2;
break;
}
+ /* FALLTHROUGH */
case LT_EXPR:
case GT_EXPR:
case LE_EXPR:
case GE_EXPR:
case MAX_EXPR:
case MIN_EXPR:
- if ((ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
- || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2)))
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_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;
if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1]))
{
type2 = type1;
@@ -1940,15 +1948,16 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
my_friendly_abort (367);
}
- /* If we're dealing with two pointer types, we need candidates
- for both of them. */
+ /* If we're dealing with two pointer types or two enumeral types,
+ we need candidates for both of them. */
if (type2 && !same_type_p (type1, type2)
&& TREE_CODE (type1) == TREE_CODE (type2)
&& (TREE_CODE (type1) == REFERENCE_TYPE
|| (TREE_CODE (type1) == POINTER_TYPE
&& TYPE_PTRMEM_P (type1) == TYPE_PTRMEM_P (type2))
|| TYPE_PTRMEMFUNC_P (type1)
- || IS_AGGR_TYPE (type1)))
+ || IS_AGGR_TYPE (type1)
+ || TREE_CODE (type1) == ENUMERAL_TYPE))
{
candidates = build_builtin_candidate
(candidates, fnname, type1, type1, args, argtypes, flags);
@@ -1977,7 +1986,12 @@ type_decays_to (type)
2) pointer-pair taking candidates. These are generated for each type
one of the input types converts to.
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 *
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 ref1, i;
+ int enum_p = 0;
tree type, argtypes[3];
/* TYPES[i] is the set of possible builtin-operator parameter types
we will consider for the Ith argument. These are represented as
@@ -2038,6 +2053,16 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
case COMPONENT_REF:
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:
ref1 = 0;
}
@@ -2086,8 +2111,8 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
if (i != 0 || ! ref1)
{
type = TYPE_MAIN_VARIANT (type_decays_to (type));
- if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE)
- types[i] = tree_cons (NULL_TREE, type, types[i]);
+ if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
+ types[i] = tree_cons (NULL_TREE, type, types[i]);
if (INTEGRAL_TYPE_P (type))
type = type_promotes_to (type);
}
@@ -2105,8 +2130,8 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
if (i != 0 || ! ref1)
{
type = TYPE_MAIN_VARIANT (type_decays_to (type));
- if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE)
- types[i] = tree_cons (NULL_TREE, type, types[i]);
+ if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
+ types[i] = tree_cons (NULL_TREE, type, types[i]);
if (INTEGRAL_TYPE_P (type))
type = type_promotes_to (type);
}
@@ -5186,21 +5211,34 @@ joust (cand1, cand2, warn)
if (winner)
return winner;
- /* or, if not that,
- F1 is a non-template function and F2 is a template function */
+ /* or, if not that, a non-template function is better than a
+ template function. */
if (! cand1->template && cand2->template)
return 1;
else if (cand1->template && ! cand2->template)
return -1;
else if (cand1->template && cand2->template)
- winner = more_specialized
- (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
- DEDUCE_ORDER,
- /* Never do unification on the 'this' parameter. */
- TREE_VEC_LENGTH (cand1->convs)
- - DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn));
+ {
+ winner = more_specialized
+ (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
+ DEDUCE_ORDER,
+ /* Never do unification on the 'this' parameter. */
+ TREE_VEC_LENGTH (cand1->convs)
+ - 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,
the context is an initialization by user-defined conversion (see
_dcl.init_ and _over.match.user_) and the standard conversion
@@ -5209,11 +5247,15 @@ joust (cand1, cand2, warn)
sequence than the standard conversion sequence from the return type
of F2 to the destination type. */
- if (! winner && cand1->second_conv)
- winner = compare_ics (cand1->second_conv, cand2->second_conv);
-
+ if (cand1->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 (! winner && cand1->fn == cand2->fn
+ if (cand1->fn == cand2->fn
&& TREE_CODE (cand1->fn) == IDENTIFIER_NODE)
{
for (i = 0; i < len; ++i)
@@ -5253,7 +5295,7 @@ tweak:
/* Extension: If the worst conversion for one candidate is worse than the
worst conversion for the other, take the first. */
- if (! winner && ! pedantic)
+ if (!pedantic)
{
int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK;
@@ -5271,7 +5313,8 @@ tweak:
return -1;
}
- return winner;
+ my_friendly_assert (!winner, 20010121);
+ return 0;
}
/* Given a list of candidates for overloading, find the best one, if any.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d89997c..31f25fb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+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>
* gcc.c-torture/execute/20010122-1.c: New test, exercise
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/overload14.C b/gcc/testsuite/g++.old-deja/g++.pt/overload14.C
new file mode 100644
index 0000000..022326e
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/overload14.C
@@ -0,0 +1,20 @@
+// 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.
+}