It occurred to me that other types of conversions use rvaluedness_matches_p,
but those uses don't affect overload resolution, so we shouldn't look at the
flag for them. Fixing that made decltype64.C compile successfully, because
the non-template candidate was a perfect match, so we now wouldn't consider
the broken template. Changing the argument to const& makes it no longer a
perfect match (because of the added const), so we again get the infinite
recursion.
This illustrates the limited nature of this optimization/recursion break; it
works for most copy/move constructors because the constructor we're looking
for is almost always a perfect match. If it happens to help improve compile
time for other calls, that's just a bonus.
gcc/cp/ChangeLog:
PR c++/96926
* call.c (perfect_conversion_p): Limit rvalueness
test to reference bindings.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/decltype64.C: Change argument to const&.
{
if (CONVERSION_RANK (conv) != cr_identity)
return false;
- if (!conv->rvaluedness_matches_p)
- return false;
- if (conv->kind == ck_ref_bind
- && !same_type_p (TREE_TYPE (conv->type),
- next_conversion (conv)->type))
- return false;
+ if (conv->kind == ck_ref_bind)
+ {
+ if (!conv->rvaluedness_matches_p)
+ return false;
+ if (!same_type_p (TREE_TYPE (conv->type),
+ next_conversion (conv)->type))
+ return false;
+ }
return true;
}
struct index
{};
-constexpr int recursive_impl(index<0u>)
+constexpr int recursive_impl(const index<0u>&)
{
return 0;
}