aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/lambda.c19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C41
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
+}