aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 221e3de..c2d62e5 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4025,9 +4025,9 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
creating a garbage BASELINK; constructors can't be inherited. */
ctors = get_class_binding (totype, complete_ctor_identifier);
+ tree to_nonref = non_reference (totype);
if (MAYBE_CLASS_TYPE_P (fromtype))
{
- tree to_nonref = non_reference (totype);
if (same_type_ignoring_top_level_qualifiers_p (to_nonref, fromtype) ||
(CLASS_TYPE_P (to_nonref) && CLASS_TYPE_P (fromtype)
&& DERIVED_FROM_P (to_nonref, fromtype)))
@@ -4111,6 +4111,22 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
tree conversion_path = TREE_PURPOSE (conv_fns);
struct z_candidate *old_candidates;
+ /* If LOOKUP_NO_CONVERSION, don't consider a conversion function that
+ would need an addional user-defined conversion, i.e. if the return
+ type differs in class-ness from the desired type. So we avoid
+ considering operator bool when calling a copy constructor.
+
+ This optimization avoids the failure in PR97600, and is allowed by
+ [temp.inst]/9: "If the function selected by overload resolution can be
+ determined without instantiating a class template definition, it is
+ unspecified whether that instantiation actually takes place." */
+ tree convtype = non_reference (TREE_TYPE (conv_fns));
+ if ((flags & LOOKUP_NO_CONVERSION)
+ && !WILDCARD_TYPE_P (convtype)
+ && (CLASS_TYPE_P (to_nonref)
+ != CLASS_TYPE_P (convtype)))
+ continue;
+
/* If we are called to convert to a reference type, we are trying to
find a direct binding, so don't even consider temporaries. If
we don't find a direct binding, the caller will try again to