aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/lambda.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-01-04 15:23:40 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-01-04 15:23:40 +0000
commit4bf07f3f5fb4fefa2702eced2291ee5d9cb5ad48 (patch)
tree9781542b18502d109be586512755bffbd4ea4100 /gcc/cp/lambda.c
parent65793e420e34fa140025b1b2d68d84e25f305f63 (diff)
downloadgcc-4bf07f3f5fb4fefa2702eced2291ee5d9cb5ad48.zip
gcc-4bf07f3f5fb4fefa2702eced2291ee5d9cb5ad48.tar.gz
gcc-4bf07f3f5fb4fefa2702eced2291ee5d9cb5ad48.tar.bz2
re PR c++/66735 ([C++14] lambda init-capture fails for const references)
cp/ PR c++/66735 * cp-tree.h (DECLTYPE_FOR_REF_CAPTURE): New. (lambda_capture_field_type): Update prototype. * lambda.c (lambda_capture_field_type): Add is_reference parm. Add referenceness here. (add_capture): Adjust lambda_capture_field_type call, refactor error checking. * pt.c (tsubst): Adjust lambda_capture_field_type call. testsuite/ PR c++/66735 * g++.dg/cpp1y/pr66735.C: New. From-SVN: r244056
Diffstat (limited to 'gcc/cp/lambda.c')
-rw-r--r--gcc/cp/lambda.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 715a61d..98fdb74 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -211,29 +211,45 @@ lambda_function (tree lambda)
}
/* Returns the type to use for the FIELD_DECL corresponding to the
- capture of EXPR.
- The caller should add REFERENCE_TYPE for capture by reference. */
+ capture of EXPR. EXPLICIT_INIT_P indicates whether this is a
+ C++14 init capture, and BY_REFERENCE_P indicates whether we're
+ capturing by reference. */
tree
-lambda_capture_field_type (tree expr, bool explicit_init_p)
+lambda_capture_field_type (tree expr, bool explicit_init_p,
+ bool by_reference_p)
{
tree type;
bool is_this = is_this_parameter (tree_strip_nop_conversions (expr));
+
if (!is_this && type_dependent_expression_p (expr))
{
type = cxx_make_type (DECLTYPE_TYPE);
DECLTYPE_TYPE_EXPR (type) = expr;
DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
DECLTYPE_FOR_INIT_CAPTURE (type) = explicit_init_p;
+ DECLTYPE_FOR_REF_CAPTURE (type) = by_reference_p;
SET_TYPE_STRUCTURAL_EQUALITY (type);
}
else if (!is_this && explicit_init_p)
{
- type = make_auto ();
- type = do_auto_deduction (type, expr, type);
+ tree auto_node = make_auto ();
+
+ type = auto_node;
+ if (by_reference_p)
+ /* Add the reference now, so deduction doesn't lose
+ outermost CV qualifiers of EXPR. */
+ type = build_reference_type (type);
+ type = do_auto_deduction (type, expr, auto_node);
}
else
- type = non_reference (unlowered_expr_type (expr));
+ {
+ type = non_reference (unlowered_expr_type (expr));
+
+ if (!is_this && by_reference_p)
+ type = build_reference_type (type);
+ }
+
return type;
}
@@ -504,9 +520,11 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
}
else
{
- type = lambda_capture_field_type (initializer, explicit_init_p);
+ type = lambda_capture_field_type (initializer, explicit_init_p,
+ by_reference_p);
if (type == error_mark_node)
return error_mark_node;
+
if (id == this_identifier && !by_reference_p)
{
gcc_assert (POINTER_TYPE_P (type));
@@ -514,17 +532,19 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
initializer = cp_build_indirect_ref (initializer, RO_NULL,
tf_warning_or_error);
}
- if (id != this_identifier && by_reference_p)
+
+ if (dependent_type_p (type))
+ ;
+ else if (id != this_identifier && by_reference_p)
{
- type = build_reference_type (type);
- if (!dependent_type_p (type) && !lvalue_p (initializer))
+ if (!lvalue_p (initializer))
error ("cannot capture %qE by reference", initializer);
}
else
{
/* Capture by copy requires a complete type. */
type = complete_type (type);
- if (!dependent_type_p (type) && !COMPLETE_TYPE_P (type))
+ if (!COMPLETE_TYPE_P (type))
{
error ("capture by copy of incomplete type %qT", type);
cxx_incomplete_type_inform (type);