]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/64496 (ICE with NSDMI and lambda)
authorJason Merrill <jason@redhat.com>
Tue, 6 Jan 2015 20:44:39 +0000 (15:44 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 6 Jan 2015 20:44:39 +0000 (15:44 -0500)
PR c++/64496
* semantics.c (process_outer_var_ref): Diagnose lambda in local
class NSDMI.

From-SVN: r219266

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

index 9c0159f812bf546b57fe2e315d09a5930d2b2404..67fd50110a2d0d1bd382d9de4aad2c01e55dc663 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/64496
+       * semantics.c (process_outer_var_ref): Diagnose lambda in local
+       class NSDMI.
+
 2015-01-06  Ville Voutilainen  <ville.voutilainen@gmail.com>
 
        PR c++/64489
index 44d9a2e801ed6e3a0e1fb97c1640afa477f0263c..551bad132e91b348f38ed56e6c2879d249f70a8f 100644 (file)
@@ -3141,8 +3141,12 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain)
     while (context != containing_function
           && LAMBDA_FUNCTION_P (containing_function))
       {
-       lambda_expr = CLASSTYPE_LAMBDA_EXPR
-         (DECL_CONTEXT (containing_function));
+       tree closure = DECL_CONTEXT (containing_function);
+       lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure);
+
+       if (TYPE_CLASS_SCOPE_P (closure))
+         /* A lambda in an NSDMI (c++/64496).  */
+         break;
 
        if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr)
            == CPLD_NONE)
@@ -3172,7 +3176,19 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain)
   else if (lambda_expr)
     {
       if (complain & tf_error)
-       error ("%qD is not captured", decl);
+       {
+         error ("%qD is not captured", decl);
+         tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr);
+         if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr)
+             == CPLD_NONE)
+           inform (location_of (closure),
+                   "the lambda has no capture-default");
+         else if (TYPE_CLASS_SCOPE_P (closure))
+           inform (0, "lambda in local class %q+T cannot "
+                   "capture variables from the enclosing context",
+                   TYPE_CONTEXT (closure));
+         inform (input_location, "%q+#D declared here", decl);
+       }
       return error_mark_node;
     }
   else
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi7.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi7.C
new file mode 100644 (file)
index 0000000..30595ef
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/64496
+// { dg-do compile { target c++11 } }
+
+template <typename> class B;
+template <typename W, typename... X>
+struct B<W(X...)> { template <typename F> B(F); };
+template <typename W, typename... X>
+template <typename F>
+B<W(X...)>::B(F) {}
+
+int
+main()
+{
+  int a;
+  struct A                     // { dg-message "lambda in local class" }
+  {
+    B<void()> l = [=] {
+      a;                       // { dg-error "not captured" }
+    };
+  };
+  [] {                         // { dg-message "capture-default" }
+    a;                         // { dg-error "not captured" }
+  };
+  A t;
+}