On Tue, Aug 29, 2017 at 3:12 PM, Jason Merrill <ja...@redhat.com> wrote: > In this testcase, when we try to call the object of 'overloader' type, > we consider the conversion function from the first lambda to void > (*)(a) and build up a surrogate call function for it. We consider how > to convert from overloader to that type, which means also looking at > the template conversion function from the second lambda, which > involves instantiating the operator() to determine the return type, > which is ill-formed. > > But the standard seems to say that we shouldn't bother to consider how > to do that conversion unless we actually choose the surrogate call > function for that type, so that's what this patch implemenets.
We also need to adjust joust to handle a null candidate.
commit f57bf1708cc3824fd0047ecd883ecb28341bcdb8 Author: Jason Merrill <ja...@redhat.com> Date: Wed Aug 30 17:30:02 2017 -0400 PR c++/82030 - ICE inheriting from multiple lambdas PR c++/80767 * call.c (compare_ics): Handle null candidate. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index c446057..9e4a5c1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9561,7 +9561,9 @@ compare_ics (conversion *ics1, conversion *ics2) return 0; else if (t1->kind == ck_user) { - if (t1->cand->fn != t2->cand->fn) + tree f1 = t1->cand ? t1->cand->fn : t1->type; + tree f2 = t2->cand ? t2->cand->fn : t2->type; + if (f1 != f2) return 0; } else diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv12.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv12.C new file mode 100644 index 0000000..16adee6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv12.C @@ -0,0 +1,18 @@ +// PR c++/80767 +// { dg-do compile { target c++11 } } + +template <typename T, typename U = T> struct A { using type = U; }; +template <typename F, typename... G> struct B : B<F>::type, B<G...>::type { + using type = B; + using B<F>::type::operator(); +}; +template <typename F> struct B<F> { using type = F; }; +struct { + template <typename... F, + typename Overload = typename B<typename A<F>::type...>::type> + Overload operator()(F...){} +} a; +int main() { + auto f = a([](int) {}, [](float) {}); + f({}); +}