aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-01-06 15:44:39 -0500
committerJason Merrill <jason@gcc.gnu.org>2015-01-06 15:44:39 -0500
commit47867b4f6556aab84701452eb0ff5a9bd2f46522 (patch)
treecd08f6d985da9274dba1a30941e244ec5d1683b4 /gcc
parent864822bd8880db5e75398a2e409dccb7545418ef (diff)
downloadgcc-47867b4f6556aab84701452eb0ff5a9bd2f46522.zip
gcc-47867b4f6556aab84701452eb0ff5a9bd2f46522.tar.gz
gcc-47867b4f6556aab84701452eb0ff5a9bd2f46522.tar.bz2
re PR c++/64496 (ICE with NSDMI and lambda)
PR c++/64496 * semantics.c (process_outer_var_ref): Diagnose lambda in local class NSDMI. From-SVN: r219266
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/semantics.c22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi7.C25
3 files changed, 50 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9c0159f..67fd501 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 44d9a2e..551bad1 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
index 0000000..30595ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi7.C
@@ -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;
+}