C++ PATCH for c++/80767, unnecessary instantiation of generic lambda

Jason Merrill jason@redhat.com
Thu Aug 31 09:09:00 GMT 2017


On Tue, Aug 29, 2017 at 3:12 PM, Jason Merrill <jason@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.
-------------- next part --------------
commit f57bf1708cc3824fd0047ecd883ecb28341bcdb8
Author: Jason Merrill <jason@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({});
+}


More information about the Gcc-patches mailing list