public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: C++ PATCH for c++/80767, unnecessary instantiation of generic lambda
@ 2017-08-31 14:30 David Edelsohn
  2017-08-31 17:49 ` Jason Merrill
  0 siblings, 1 reply; 5+ messages in thread
From: David Edelsohn @ 2017-08-31 14:30 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

Jason,

The recent patch for 82030

            PR c++/82030 - ICE inheriting from multiple lambdas

            PR c++/80767
            * call.c (compare_ics): Handle null candidate.

causes bootstrap to fail for AIX due to a segfault ICE building
libstdc++ with stage1 compiler.

- David

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: C++ PATCH for c++/80767, unnecessary instantiation of generic lambda
  2017-08-31 14:30 C++ PATCH for c++/80767, unnecessary instantiation of generic lambda David Edelsohn
@ 2017-08-31 17:49 ` Jason Merrill
  2017-09-01 13:47   ` David Edelsohn
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2017-08-31 17:49 UTC (permalink / raw)
  To: David Edelsohn; +Cc: GCC Patches

On Thu, Aug 31, 2017 at 9:37 AM, David Edelsohn <dje.gcc@gmail.com> wrote:
> Jason,
>
> The recent patch for 82030
>
>             PR c++/82030 - ICE inheriting from multiple lambdas
>
>             PR c++/80767
>             * call.c (compare_ics): Handle null candidate.
>
> causes bootstrap to fail for AIX due to a segfault ICE building
> libstdc++ with stage1 compiler.

Hmm, strange.  Testcase?

Jason

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: C++ PATCH for c++/80767, unnecessary instantiation of generic lambda
  2017-08-31 17:49 ` Jason Merrill
@ 2017-09-01 13:47   ` David Edelsohn
  0 siblings, 0 replies; 5+ messages in thread
From: David Edelsohn @ 2017-09-01 13:47 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

On Thu, Aug 31, 2017 at 1:16 PM, Jason Merrill <jason@redhat.com> wrote:
> On Thu, Aug 31, 2017 at 9:37 AM, David Edelsohn <dje.gcc@gmail.com> wrote:
>> Jason,
>>
>> The recent patch for 82030
>>
>>             PR c++/82030 - ICE inheriting from multiple lambdas
>>
>>             PR c++/80767
>>             * call.c (compare_ics): Handle null candidate.
>>
>> causes bootstrap to fail for AIX due to a segfault ICE building
>> libstdc++ with stage1 compiler.
>
> Hmm, strange.  Testcase?

I cannot reproduce the bootstrap failure with your patch, so I cannot
explain it. I hope that it is not the beginning of a hardware failure
in the GNU Farm AIX system.

- David

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: C++ PATCH for c++/80767, unnecessary instantiation of generic lambda
  2017-08-29 20:02 Jason Merrill
@ 2017-08-31  9:09 ` Jason Merrill
  0 siblings, 0 replies; 5+ messages in thread
From: Jason Merrill @ 2017-08-31  9:09 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 783 bytes --]

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.

[-- Attachment #2: 82030.diff --]
[-- Type: text/plain, Size: 1488 bytes --]

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({});
+}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* C++ PATCH for c++/80767, unnecessary instantiation of generic lambda
@ 2017-08-29 20:02 Jason Merrill
  2017-08-31  9:09 ` Jason Merrill
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2017-08-29 20:02 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 679 bytes --]

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.

Tested x86_64-pc-linux-gnu, applying to trunk.

[-- Attachment #2: 80767.diff --]
[-- Type: text/plain, Size: 2150 bytes --]

commit b987db09b63a8fc89f0d6cb2712c1ba8ee47eefd
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Aug 28 17:38:59 2017 -0400

            PR c++/80767 - unnecessary instantiation of generic lambda
    
            * call.c (convert_like_real): Call build_user_type_conversion_1 if
            cand is null.
            (add_conv_candidate): Build a ck_user conversion with no candidate.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 70c2f86..c446057 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2278,8 +2278,10 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
 
       if (i == 0)
 	{
-	  t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
-				   flags, complain);
+	  t = build_identity_conv (argtype, NULL_TREE);
+	  t = build_conv (ck_user, totype, t);
+	  /* Leave the 'cand' field null; we'll figure out the conversion in
+	     convert_like_real if this candidate is chosen.  */
 	  convert_type = totype;
 	}
       else if (parmnode == void_list_node)
@@ -6692,6 +6694,13 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     case ck_user:
       {
 	struct z_candidate *cand = convs->cand;
+
+	if (cand == NULL)
+	  /* We chose the surrogate function from add_conv_candidate, now we
+	     actually need to build the conversion.  */
+	  cand = build_user_type_conversion_1 (totype, expr,
+					       LOOKUP_NO_CONVERSION, complain);
+
 	tree convfn = cand->fn;
 
 	/* When converting from an init list we consider explicit
diff --git a/gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C b/gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C
new file mode 100644
index 0000000..75ef586
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C
@@ -0,0 +1,23 @@
+// PR c++/80767
+// { dg-options -std=c++17 }
+
+template <typename... Fs> 
+struct overloader : Fs...
+{
+    overloader(Fs... fs) 
+        : Fs(fs)...
+    { } 
+
+    using Fs::operator()...;
+};
+
+struct a { void foo() { } };
+struct b { void bar() { } };
+struct c { void bar() { } };
+
+int main() {
+    overloader{
+        [](a x) { x.foo(); },
+        [](auto x) { x.bar(); }
+    }(a{});
+}

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-09-01 13:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-31 14:30 C++ PATCH for c++/80767, unnecessary instantiation of generic lambda David Edelsohn
2017-08-31 17:49 ` Jason Merrill
2017-09-01 13:47   ` David Edelsohn
  -- strict thread matches above, loose matches on Subject: below --
2017-08-29 20:02 Jason Merrill
2017-08-31  9:09 ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).