aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-03-07 07:02:02 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-03-07 07:02:02 +0000
commit3d93842695fa7650032bed46338d3f1339cbb42c (patch)
tree9fb76bbd4262b032899b2cd77f6653508a644d54 /gcc
parentea67bef4705c2012dfe5c35ff15cb0ebc78ea2da (diff)
downloadgcc-3d93842695fa7650032bed46338d3f1339cbb42c.zip
gcc-3d93842695fa7650032bed46338d3f1339cbb42c.tar.gz
gcc-3d93842695fa7650032bed46338d3f1339cbb42c.tar.bz2
call.c (merge_conversion_sequences): New function.
* call.c (merge_conversion_sequences): New function. (build_conv): Set ICS_USER_FLAG for USER_CONVs. (convert_class_to_reference): Correct handling of second standard conversion sequence in a user-defined conversion sequence. (build_user_type_conversion_1): Use merge_conversion_sequences. * cp-tree.def: Add comments for CONV nodes. * g++.dg/init/ref3.C: New test. From-SVN: r63930
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/call.c101
-rw-r--r--gcc/cp/cp-tree.def12
-rw-r--r--gcc/cp/rtti.c9
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/init/ref3.C12
6 files changed, 112 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9044978..668c6e7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2003-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (merge_conversion_sequences): New function.
+ (build_conv): Set ICS_USER_FLAG for USER_CONVs.
+ (convert_class_to_reference): Correct handling of second
+ standard conversion sequence in a user-defined conversion
+ sequence.
+ (build_user_type_conversion_1): Use merge_conversion_sequences.
+ * cp-tree.def: Add comments for CONV nodes.
+
2003-03-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
* error.c (init_error): Use C90 prototype style.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c5fd77b..15dbbe1 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1,6 +1,6 @@
/* Functions related to invoking methods and overloaded functions.
- Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) and
modified by Brendan Kehoe (brendan@cygnus.com).
@@ -106,6 +106,7 @@ static tree call_builtin_trap (void);
static tree prep_operand (tree);
static void add_candidates (tree, tree, tree, tree,
int, struct z_candidate **);
+static tree merge_conversion_sequences (tree, tree);
tree
build_vfield_ref (tree datum, tree type)
@@ -560,7 +561,12 @@ struct z_candidate GTY(()) {
tree fn;
/* The arguments to use when calling this function. */
tree args;
+ /* The implicit conversion sequences for each of the arguments to
+ FN. */
tree convs;
+ /* If FN is a user-defined conversion, the standard conversion
+ sequence from the type returned by FN to the desired destination
+ type. */
tree second_conv;
int viable;
/* If FN is a member function, the binfo indicating the path used to
@@ -667,7 +673,7 @@ build_conv (enum tree_code code, tree type, tree from)
break;
}
ICS_STD_RANK (t) = rank;
- ICS_USER_FLAG (t) = ICS_USER_FLAG (from);
+ ICS_USER_FLAG (t) = (code == USER_CONV || ICS_USER_FLAG (from));
ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);
return t;
}
@@ -1034,15 +1040,15 @@ convert_class_to_reference (tree t, tree s, tree expr)
LOOKUP_NORMAL);
if (cand)
- {
- conv = build1 (IDENTITY_CONV, s, expr);
- conv = build_conv (USER_CONV, TREE_TYPE (TREE_TYPE (cand->fn)),
- conv);
- TREE_OPERAND (conv, 1) = build_zc_wrapper (cand);
- ICS_USER_FLAG (conv) = 1;
- cand->second_conv
- = direct_reference_binding (reference_type, conv);
- }
+ /* Build a standard conversion sequence indicating the
+ binding from the reference type returned by the
+ function to the desired REFERENCE_TYPE. */
+ cand->second_conv
+ = (direct_reference_binding
+ (reference_type,
+ build1 (IDENTITY_CONV,
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
+ NULL_TREE)));
}
conversions = TREE_CHAIN (conversions);
}
@@ -1063,11 +1069,21 @@ convert_class_to_reference (tree t, tree s, tree expr)
build_this (expr),
TREE_CHAIN (cand->args));
- conv = cand->second_conv;
+ /* Build a user-defined conversion sequence representing the
+ conversion. */
+ conv = build_conv (USER_CONV,
+ TREE_TYPE (TREE_TYPE (cand->fn)),
+ build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));
+ TREE_OPERAND (conv, 1) = build_zc_wrapper (cand);
+
+ /* Merge it with the standard conversion sequence from the
+ conversion function's return type to the desired type. */
+ cand->second_conv = merge_conversion_sequences (conv, cand->second_conv);
+
if (cand->viable == -1)
ICS_BAD_FLAG (conv) = 1;
- return conv;
+ return cand->second_conv;
}
/* A reference of the indicated TYPE is being bound directly to the
@@ -1077,7 +1093,13 @@ convert_class_to_reference (tree t, tree s, tree expr)
static tree
direct_reference_binding (tree type, tree conv)
{
- tree t = TREE_TYPE (type);
+ tree t;
+
+ my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 20030306);
+ my_friendly_assert (TREE_CODE (TREE_TYPE (conv)) != REFERENCE_TYPE,
+ 20030306);
+
+ t = TREE_TYPE (type);
/* [over.ics.rank]
@@ -2428,6 +2450,35 @@ print_z_candidates (struct z_candidate *candidates)
}
}
+/* USER_SEQ is a user-defined conversion sequence, beginning with a
+ USER_CONV. STD_SEQ is the standard conversion sequence applied to
+ the result of the conversion function to convert it to the final
+ desired type. Merge the the two sequences into a single sequence,
+ and return the merged sequence. */
+
+static tree
+merge_conversion_sequences (tree user_seq, tree std_seq)
+{
+ tree *t;
+
+ my_friendly_assert (TREE_CODE (user_seq) == USER_CONV,
+ 20030306);
+
+ /* Find the end of the second conversion sequence. */
+ t = &(std_seq);
+ while (TREE_CODE (*t) != IDENTITY_CONV)
+ t = &TREE_OPERAND (*t, 0);
+
+ /* Replace the identity conversion with the user conversion
+ sequence. */
+ *t = user_seq;
+
+ /* The entire sequence is a user-conversion sequence. */
+ ICS_USER_FLAG (std_seq) = 1;
+
+ return std_seq;
+}
+
/* Returns the best overload candidate to perform the requested
conversion. This function is used for three the overloading situations
described in [over.match.copy], [over.match.conv], and [over.match.ref].
@@ -2439,7 +2490,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
{
struct z_candidate *candidates, *cand;
tree fromtype = TREE_TYPE (expr);
- tree ctors = NULL_TREE, convs = NULL_TREE, *p;
+ tree ctors = NULL_TREE, convs = NULL_TREE;
tree args = NULL_TREE;
/* We represent conversion within a hierarchy using RVALUE_CONV and
@@ -2583,18 +2634,20 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
return cand;
}
- for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; )
- p = &(TREE_OPERAND (*p, 0));
-
- *p = build
+ /* Build the user conversion sequence. */
+ convs = build_conv
(USER_CONV,
(DECL_CONSTRUCTOR_P (cand->fn)
? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
- expr, build_zc_wrapper (cand));
-
- ICS_USER_FLAG (cand->second_conv) = ICS_USER_FLAG (*p) = 1;
+ build1 (IDENTITY_CONV, TREE_TYPE (expr), expr));
+ TREE_OPERAND (convs, 1) = build_zc_wrapper (cand);
+
+ /* Combine it with the second conversion sequence. */
+ cand->second_conv = merge_conversion_sequences (convs,
+ cand->second_conv);
+
if (cand->viable == -1)
- ICS_BAD_FLAG (cand->second_conv) = ICS_BAD_FLAG (*p) = 1;
+ ICS_BAD_FLAG (cand->second_conv) = 1;
return cand;
}
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index f621844..86103c4 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -1,8 +1,8 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the GNU C++ compiler (see tree.def
for the standard codes).
- Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998, 2003,
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
@@ -270,7 +270,13 @@ DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1)
DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
-/* And some codes for expressing conversions for overload resolution. */
+/* The following codes are used to represent implicit conversion
+ sequences, in the sense of [over.best.ics]. The conversion
+ sequences are connected through their first operands, with the
+ first conversion to be performed at the end of the chain.
+
+ The innermost conversion (i.e, the one at the end of the chain) is
+ always an IDENTITY_CONV, corresponding to the identity conversion. */
DEFTREECODE (IDENTITY_CONV, "identity_conv", 'e', 1)
DEFTREECODE (LVALUE_CONV, "lvalue_conv", 'e', 1)
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 9ebae8b..eab85f7 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -378,13 +378,8 @@ get_tinfo_decl (tree type)
static tree
get_tinfo_ptr (tree type)
{
- tree exp = get_tinfo_decl (type);
-
- /* Convert to type_info type. */
- exp = build_unary_op (ADDR_EXPR, exp, 0);
- exp = ocp_convert (type_info_ptr_type, exp, CONV_REINTERPRET, 0);
-
- return exp;
+ return build_nop (type_info_ptr_type,
+ build_address (get_tinfo_decl (type)));
}
/* Return the type_info object for TYPE. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9fabfd1..3671589 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,7 @@
2003-03-06 Mark Mitchell <mark@codesourcery.com>
+ * g++.dg/init/ref3.C: New test.
+
PR c++/9965
* g++.dg/init/ref2.C: New test.
diff --git a/gcc/testsuite/g++.dg/init/ref3.C b/gcc/testsuite/g++.dg/init/ref3.C
new file mode 100644
index 0000000..776f2d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/ref3.C
@@ -0,0 +1,12 @@
+struct Base { };
+struct Derived : public Base { };
+struct Choose {
+ operator Base&();
+ operator Derived&();
+};
+
+void f()
+{
+ Choose c;
+ Base& ref = c;
+}