diff options
author | Jason Merrill <jason@redhat.com> | 2015-01-06 15:44:39 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-01-06 15:44:39 -0500 |
commit | 47867b4f6556aab84701452eb0ff5a9bd2f46522 (patch) | |
tree | cd08f6d985da9274dba1a30941e244ec5d1683b4 /gcc | |
parent | 864822bd8880db5e75398a2e409dccb7545418ef (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi7.C | 25 |
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; +} |