]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix ICE with lambda in member operator (PR93279)
authorJason Merrill <jason@redhat.com>
Fri, 24 Jan 2020 23:20:56 +0000 (18:20 -0500)
committerJason Merrill <jason@redhat.com>
Tue, 28 Jan 2020 14:52:57 +0000 (09:52 -0500)
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.

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C [new file with mode: 0644]

index 69efbb99af47d1a00f5e46db9195d3b0ce41177a..d8fc647120e0f74f7ee670ee5e3d142932b374be 100644 (file)
@@ -1,3 +1,9 @@
+2020-01-28  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-27  Nathan Sidwell  <nathan@acm.org>
 
        PR c++/91826
index 7b5ae9d3990dc7bc08e3feee06f17bfd67634221..8999c5ad4a74d0253d1ac544f5df0e9c6a91703a 100644 (file)
@@ -7626,6 +7626,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 (file)
index 0000000..faaff68
--- /dev/null
@@ -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;
+}