diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/lambda.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C | 41 |
2 files changed, 56 insertions, 4 deletions
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index f68c68c..c39a2bc 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -195,7 +195,9 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, tree type; bool is_this = is_this_parameter (tree_strip_nop_conversions (expr)); - if (!is_this && explicit_init_p) + if (is_this) + type = TREE_TYPE (expr); + else if (explicit_init_p) { tree auto_node = make_auto (); @@ -209,7 +211,7 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, else type = do_auto_deduction (type, expr, auto_node); } - else if (!is_this && type_dependent_expression_p (expr)) + else if (type_dependent_expression_p (expr)) { type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = expr; @@ -219,10 +221,19 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, } else { + if (!by_reference_p && is_capture_proxy (expr)) + { + /* When capturing by-value another capture proxy from an enclosing + lambda, consider the type of the corresponding field instead, + as the proxy may be additionally const-qualifed if the enclosing + lambda is non-mutable (PR94376). */ + gcc_assert (TREE_CODE (DECL_VALUE_EXPR (expr)) == COMPONENT_REF); + expr = TREE_OPERAND (DECL_VALUE_EXPR (expr), 1); + } + type = non_reference (unlowered_expr_type (expr)); - if (!is_this - && (by_reference_p || TREE_CODE (type) == FUNCTION_TYPE)) + if (by_reference_p || TREE_CODE (type) == FUNCTION_TYPE) type = build_reference_type (type); } diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C new file mode 100644 index 0000000..ff7da3b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C @@ -0,0 +1,41 @@ +// PR c++/94376 +// { dg-do compile { target c++11 } } + +int main() { + // We used to incorrectly reject the first two cases. + int i = 0; + [=] () { + [=] () mutable { + ++i; + }; + }; + +#if __cpp_init_captures + [j=0] () { + [=] () mutable { + ++j; + }; + }; +#endif + + [=] () { + [&] () mutable { + ++i; // { dg-error "read-only" } + }; + }; + + const int j = 0; + [=] () { + [=] () mutable { + ++j; // { dg-error "read-only" } + }; + }; + +#if __cpp_init_captures + [j=0] () { + [&] () mutable { + ++j; // { dg-error "read-only" } + }; + }; +#endif +} |