[gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] c++: Fix ICE with lambda in member operator (PR93279)

Martin Liska marxin@gcc.gnu.org
Mon Mar 30 10:28:04 GMT 2020


https://gcc.gnu.org/g:8b91e848130e45b427599ad30e99f96e447ea9aa

commit 8b91e848130e45b427599ad30e99f96e447ea9aa
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Jan 24 18:20:56 2020 -0500

    c++: Fix ICE with lambda in member operator (PR93279)
    
    Here the problem was that we were remembering the lookup in template scope,
    and then trying to reuse that lookup in the instantiation without
    substituting into it at all.  The simplest solution is to not try to
    remember a lookup that finds a class-scope declaration, as in that case
    doing the normal lookup again at instantiation time will always find the
    right declarations.
    
            PR c++/93279 - ICE with lambda in member operator.
            * name-lookup.c (maybe_save_operator_binding): Don't remember
            class-scope bindings.

Diff:
---
 gcc/cp/ChangeLog                                      |  6 ++++++
 gcc/cp/name-lookup.c                                  |  6 ++++++
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C | 15 +++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cddf169ea5b..764b9ccffa3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-24  Jason Merrill  <jason@redhat.com>
+
+	PR c++/93279 - ICE with lambda in member operator.
+	* name-lookup.c (maybe_save_operator_binding): Don't remember
+	class-scope bindings.
+
 2020-01-24  Jason Merrill  <jason@redhat.com>
 
 	PR c++/93377 - ICE with member alias in constraint.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index cd7a5816e46..572100766cb 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -7616,6 +7616,12 @@ maybe_save_operator_binding (tree e)
 
   if (!fns && (fns = op_unqualified_lookup (fnname)))
     {
+      tree fn = get_first_fn (fns);
+      if (DECL_CLASS_SCOPE_P (fn))
+	/* We don't need to remember class-scope functions, normal unqualified
+	   lookup will find them again.  */
+	return;
+
       bindings = tree_cons (fnname, fns, bindings);
       if (attr)
 	TREE_VALUE (attr) = bindings;
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C
new file mode 100644
index 00000000000..faaff68b968
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C
@@ -0,0 +1,15 @@
+// PR c++/93279
+// { dg-do compile { target c++11 } }
+
+template <typename T> struct B { using f = int; };
+template <typename T, int N> struct E {
+  template <typename U, typename B<E>::f = 0>
+  void operator*(U l) { [l](T m) { m * l; }; }
+};
+
+int
+main ()
+{
+  E<E<float, 4>, 1> n;
+  n * 4.f;
+}


More information about the Gcc-cvs mailing list