diff options
author | Jason Merrill <jason@redhat.com> | 2011-09-12 14:04:46 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-09-12 14:04:46 -0400 |
commit | 62a405ddf395d4804d18954fc6b09d90da345d39 (patch) | |
tree | f40ab43f4e4356b49795fd8bf149f118cde02724 | |
parent | e495f6b0c06db941cd213941fe659127eedb13b1 (diff) | |
download | gcc-62a405ddf395d4804d18954fc6b09d90da345d39.zip gcc-62a405ddf395d4804d18954fc6b09d90da345d39.tar.gz gcc-62a405ddf395d4804d18954fc6b09d90da345d39.tar.bz2 |
* call.c (convert_class_to_reference)
(convert_class_to_reference_1): Remove.
(reference_binding): Use build_user_type_conversion_1 instead.
From-SVN: r178789
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/call.c | 165 | ||||
-rw-r--r-- | libstdc++-v3/ChangeLog | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc | 4 |
4 files changed, 17 insertions, 161 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 476173d..772ba51 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2011-09-12 Jason Merrill <jason@redhat.com> + * call.c (convert_class_to_reference) + (convert_class_to_reference_1): Remove. + (reference_binding): Use build_user_type_conversion_1 instead. + * call.c (initialize_reference): Add flags parm. * decl.c (grok_reference_init): Likewise. (check_initializer): Pass it. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7912fad..d58ed13 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -202,7 +202,6 @@ static struct z_candidate *add_candidate static tree source_type (conversion *); static void add_warning (struct z_candidate *, struct z_candidate *); static bool reference_compatible_p (tree, tree); -static conversion *convert_class_to_reference (tree, tree, tree, int); static conversion *direct_reference_binding (tree, conversion *); static bool promoted_arithmetic_type_p (tree); static conversion *conditional_conversion (tree, tree); @@ -1352,160 +1351,6 @@ reference_compatible_p (tree t1, tree t2) && at_least_as_qualified_p (t1, t2)); } -/* Determine whether or not the EXPR (of class type S) can be - converted to T as in [over.match.ref]. */ - -static conversion * -convert_class_to_reference_1 (tree reference_type, tree s, tree expr, int flags) -{ - tree conversions; - tree first_arg; - conversion *conv; - tree t; - struct z_candidate *candidates; - struct z_candidate *cand; - bool any_viable_p; - - if (!expr) - return NULL; - - conversions = lookup_conversions (s); - if (!conversions) - return NULL; - - /* [over.match.ref] - - Assuming that "cv1 T" is the underlying type of the reference - being initialized, and "cv S" is the type of the initializer - expression, with S a class type, the candidate functions are - selected as follows: - - --The conversion functions of S and its base classes are - considered. Those that are not hidden within S and yield type - "reference to cv2 T2", where "cv1 T" is reference-compatible - (_dcl.init.ref_) with "cv2 T2", are candidate functions. - - The argument list has one argument, which is the initializer - expression. */ - - candidates = 0; - - /* Conceptually, we should take the address of EXPR and put it in - the argument list. Unfortunately, however, that can result in - error messages, which we should not issue now because we are just - trying to find a conversion operator. Therefore, we use NULL, - cast to the appropriate type. */ - first_arg = build_int_cst (build_pointer_type (s), 0); - - t = TREE_TYPE (reference_type); - - /* We're performing a user-defined conversion to a desired type, so set - this for the benefit of add_candidates. */ - flags |= LOOKUP_NO_CONVERSION; - - for (; conversions; conversions = TREE_CHAIN (conversions)) - { - tree fns = TREE_VALUE (conversions); - tree binfo = TREE_PURPOSE (conversions); - struct z_candidate *old_candidates = candidates;; - - add_candidates (fns, first_arg, NULL, reference_type, - NULL_TREE, false, - binfo, TYPE_BINFO (s), - flags, &candidates); - - for (cand = candidates; cand != old_candidates; cand = cand->next) - { - /* Now, see if the conversion function really returns - an lvalue of the appropriate type. From the - point of view of unification, simply returning an - rvalue of the right type is good enough. */ - tree f = cand->fn; - tree t2 = TREE_TYPE (TREE_TYPE (f)); - if (cand->viable == 0) - /* Don't bother looking more closely. */; - else if (TREE_CODE (t2) != REFERENCE_TYPE - || !reference_compatible_p (t, TREE_TYPE (t2))) - { - /* No need to set cand->reason here; this is most likely - an ambiguous match. If it's not, either this candidate - will win, or we will have identified a reason for it - losing already. */ - cand->viable = 0; - } - else - { - conversion *identity_conv; - /* Build a standard conversion sequence indicating the - binding from the reference type returned by the - function to the desired REFERENCE_TYPE. */ - identity_conv - = build_identity_conv (TREE_TYPE (TREE_TYPE - (TREE_TYPE (cand->fn))), - NULL_TREE); - cand->second_conv - = (direct_reference_binding - (reference_type, identity_conv)); - cand->second_conv->rvaluedness_matches_p - = TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn))) - == TYPE_REF_IS_RVALUE (reference_type); - cand->second_conv->bad_p |= cand->convs[0]->bad_p; - - /* Don't allow binding of lvalues to rvalue references. */ - if (TYPE_REF_IS_RVALUE (reference_type) - /* Function lvalues are OK, though. */ - && TREE_CODE (TREE_TYPE (reference_type)) != FUNCTION_TYPE - && !TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn)))) - cand->second_conv->bad_p = true; - } - } - } - - candidates = splice_viable (candidates, pedantic, &any_viable_p); - /* If none of the conversion functions worked out, let our caller - know. */ - if (!any_viable_p) - return NULL; - - cand = tourney (candidates); - if (!cand) - return NULL; - - /* Now that we know that this is the function we're going to use fix - the dummy first argument. */ - gcc_assert (cand->first_arg == NULL_TREE - || integer_zerop (cand->first_arg)); - cand->first_arg = build_this (expr); - - /* Build a user-defined conversion sequence representing the - conversion. */ - conv = build_conv (ck_user, - TREE_TYPE (TREE_TYPE (cand->fn)), - build_identity_conv (TREE_TYPE (expr), expr)); - conv->cand = cand; - - if (cand->viable == -1) - conv->bad_p = true; - - /* 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); - - return cand->second_conv; -} - -/* Wrapper for above. */ - -static conversion * -convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) -{ - conversion *ret; - bool subtime = timevar_cond_start (TV_OVERLOAD); - ret = convert_class_to_reference_1 (reference_type, s, expr, flags); - timevar_cond_stop (TV_OVERLOAD, subtime); - return ret; -} - /* A reference of the indicated TYPE is being bound directly to the expression represented by the implicit conversion sequence CONV. Return a conversion sequence for this binding. */ @@ -1715,9 +1560,9 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) the reference is bound to the lvalue result of the conversion in the second case. */ - conv = convert_class_to_reference (rto, from, expr, flags); - if (conv) - return conv; + z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags); + if (cand) + return cand->second_conv; } /* From this point on, we conceptually need temporaries, even if we @@ -3477,7 +3322,7 @@ add_list_candidates (tree fns, tree first_arg, /* 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]. - If TOTYPE is a REFERENCE_TYPE, we're trying to find an lvalue binding as + If TOTYPE is a REFERENCE_TYPE, we're trying to find a direct binding as per [dcl.init.ref], so we ignore temporary bindings. */ static struct z_candidate * @@ -3636,6 +3481,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) yield type T or a type that can be converted to type T with a qualification conversion (4.4) are also candidate functions. */ + /* 13.3.1.6 doesn't have a parallel restriction, but it should; + I've raised this issue with the committee. --jason 9/2011 */ cand->viable = -1; cand->reason = explicit_conversion_rejection (rettype, totype); } diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8edaae5..8cd719c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2011-09-12 Jason Merrill <jason@redhat.com> + + * testsuite/20_util/is_constructible/value-2.cc: Adjust + expected values. + 2011-09-11 Daniel Krugler <daniel.kruegler@googlemail.com> PR libstdc++/50159 diff --git a/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc b/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc index 9e4bd97..24fde93 100644 --- a/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc +++ b/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc @@ -236,8 +236,8 @@ static_assert(std::is_constructible<const int&, static_assert(std::is_constructible<const int&, ExplicitTo<int&>>::value, "Error"); -static_assert(std::is_constructible<B&&, ExplicitTo<D&&>>::value, "Error"); -static_assert(std::is_constructible<B&&, ExplicitTo<D&&>&>::value, "Error"); +static_assert(!std::is_constructible<B&&, ExplicitTo<D&&>>::value, "Error"); +static_assert(!std::is_constructible<B&&, ExplicitTo<D&&>&>::value, "Error"); static_assert(!std::is_constructible<B&, B&&>::value, "Error"); static_assert(!std::is_constructible<D&, B&&>::value, "Error"); |