From 47867b4f6556aab84701452eb0ff5a9bd2f46522 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 6 Jan 2015 15:44:39 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/semantics.c | 22 +++++++++++++--- .../g++.dg/cpp0x/lambda/lambda-nsdmi7.C | 25 +++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi7.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9c0159f812b..67fd50110a2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-01-06 Jason Merrill + + PR c++/64496 + * semantics.c (process_outer_var_ref): Diagnose lambda in local + class NSDMI. + 2015-01-06 Ville Voutilainen PR c++/64489 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 44d9a2e801e..551bad132e9 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 00000000000..30595ef6c10 --- /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 class B; +template +struct B { template B(F); }; +template +template +B::B(F) {} + +int +main() +{ + int a; + struct A // { dg-message "lambda in local class" } + { + B l = [=] { + a; // { dg-error "not captured" } + }; + }; + [] { // { dg-message "capture-default" } + a; // { dg-error "not captured" } + }; + A t; +} -- 2.30.2