PR c++/84520 - ICE with generic lambda in NSDMI.
authorJason Merrill <jason@redhat.com>
Tue, 27 Feb 2018 02:44:26 +0000 (21:44 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 27 Feb 2018 02:44:26 +0000 (21:44 -0500)
* lambda.c (lambda_expr_this_capture): Don't look for fake NSDMI
'this' in a generic lambda instantiation.

From-SVN: r258021

gcc/cp/ChangeLog
gcc/cp/lambda.c
gcc/testsuite/g++.dg/cpp1y/lambda-generic-nsdmi1.C [new file with mode: 0644]

index 3a2a17d..fe5c786 100644 (file)
@@ -1,5 +1,9 @@
 2018-02-26  Jason Merrill  <jason@redhat.com>
 
+       PR c++/84520 - ICE with generic lambda in NSDMI.
+       * lambda.c (lambda_expr_this_capture): Don't look for fake NSDMI
+       'this' in a generic lambda instantiation.
+
        PR c++/84559 - ICE with constexpr VLA.
        * constexpr.c (ensure_literal_type_for_constexpr_object): Check
        for constexpr variable with VLA type.
index 6a79826..3f77df0 100644 (file)
@@ -758,11 +758,14 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
                                     lambda_stack);
 
          if (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)
+             && !COMPLETE_TYPE_P (LAMBDA_EXPR_CLOSURE (tlambda))
              && TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)) == FIELD_DECL)
            {
              /* In an NSDMI, we don't have a function to look up the decl in,
                 but the fake 'this' pointer that we're using for parsing is
-                in scope_chain.  */
+                in scope_chain.  But if the closure is already complete, we're
+                in an instantiation of a generic lambda, and the fake 'this'
+                is gone.  */
              init = scope_chain->x_current_class_ptr;
              gcc_checking_assert
                (init && (TREE_TYPE (TREE_TYPE (init))
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-nsdmi1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-nsdmi1.C
new file mode 100644 (file)
index 0000000..89ce519
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/84520
+// { dg-do compile { target c++14 } }
+
+struct A
+{
+  static void foo(int);
+  void (*f)(int) = [](auto i) { foo(i); };
+};