diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-03-07 07:02:02 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-03-07 07:02:02 +0000 |
commit | 3d93842695fa7650032bed46338d3f1339cbb42c (patch) | |
tree | 9fb76bbd4262b032899b2cd77f6653508a644d54 /gcc | |
parent | ea67bef4705c2012dfe5c35ff15cb0ebc78ea2da (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/call.c | 101 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 12 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/ref3.C | 12 |
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; +} |