On 8/21/23 21:51, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look like
a reasonable approach?  I didn't observe any compile time/memory impact
of this change.

-- >8 --

As described in detail in the PR, CWG 2369 has the surprising
consequence of introducing constraint recursion in seemingly valid and
innocent code.

This patch attempts to fix this surpising behavior for the majority
of problematic use cases.  Rather than checking satisfaction before
_all_ non-dependent conversions, as specified by the CWG issue,
this patch makes us first check "safe" non-dependent conversions,
then satisfaction, then followed by "unsafe" non-dependent conversions.
In this case, a conversion is "safe" if computing it is guaranteed
to not induce template instantiation.  This patch heuristically
determines "safety" by checking for a constructor template or conversion
function template in the (class) parm or arg types respectively.
If neither type has such a member, then computing the conversion
should not induce instantiation (modulo satisfaction checking of
non-template constructor and conversion functions I suppose).

+         /* We're checking only non-instantiating conversions.
+            A conversion may instantiate only if it's to/from a
+            class type that has a constructor template/conversion
+            function template.  */
+         tree parm_nonref = non_reference (parm);
+         tree type_nonref = non_reference (type);
+
+         if (CLASS_TYPE_P (parm_nonref))
+           {
+             if (!COMPLETE_TYPE_P (parm_nonref)
+                 && CLASSTYPE_TEMPLATE_INSTANTIATION (parm_nonref))
+               return unify_success (explain_p);
+
+             tree ctors = get_class_binding (parm_nonref,
+                                             complete_ctor_identifier);
+             for (tree ctor : lkp_range (ctors))
+               if (TREE_CODE (ctor) == TEMPLATE_DECL)
+                 return unify_success (explain_p);

Today we discussed maybe checking CLASSTYPE_NON_AGGREGATE?

Also, instantiation can also happen when checking for conversion to a pointer or reference to base class.

Jason

Reply via email to