Commit 27626519 by Jason Merrill

PR c++/90732 - ICE with VLA capture and generic lambda.

We were failing to handle VLA capture in tsubst_lambda_expr; initially
building a DECLTYPE_TYPE for the capture and then tsubsting it doesn't give
the special VLA handling.  So with this patch we call add_capture again for
VLAs.

	* pt.c (tsubst_lambda_expr): Repeat add_capture for VLAs.
parent a312c801
2020-01-21 Jason Merrill <jason@redhat.com>
PR c++/90732 - ICE with VLA capture and generic lambda.
* pt.c (tsubst_lambda_expr): Repeat add_capture for VLAs.
2020-01-21 Iain Sandoe <iain@sandoe.co.uk>
Bin Cheng <bin.cheng@linux.alibaba.com>
......
......@@ -18751,6 +18751,36 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
cap = TREE_CHAIN (cap))
{
tree ofield = TREE_PURPOSE (cap);
tree init = TREE_VALUE (cap);
if (PACK_EXPANSION_P (init))
init = tsubst_pack_expansion (init, args, complain, in_decl);
else
init = tsubst_copy_and_build (init, args, complain, in_decl,
/*fn*/false, /*constexpr*/false);
if (init == error_mark_node)
return error_mark_node;
if (init && TREE_CODE (init) == TREE_LIST)
init = build_x_compound_expr_from_list (init, ELK_INIT, complain);
if (!processing_template_decl
&& init && TREE_CODE (init) != TREE_VEC
&& variably_modified_type_p (TREE_TYPE (init), NULL_TREE))
{
/* For a VLA, simply tsubsting the field type won't work, we need to
go through add_capture again. XXX do we want to do this for all
captures? */
tree name = (get_identifier
(IDENTIFIER_POINTER (DECL_NAME (ofield)) + 2));
tree ftype = TREE_TYPE (ofield);
bool by_ref = (TYPE_REF_P (ftype)
|| (TREE_CODE (ftype) == DECLTYPE_TYPE
&& DECLTYPE_FOR_REF_CAPTURE (ftype)));
add_capture (r, name, init, by_ref, !DECL_NORMAL_CAPTURE_P (ofield));
continue;
}
if (PACK_EXPANSION_P (ofield))
ofield = PACK_EXPANSION_PATTERN (ofield);
tree field = tsubst_decl (ofield, args, complain);
......@@ -18765,13 +18795,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (field == error_mark_node)
return error_mark_node;
tree init = TREE_VALUE (cap);
if (PACK_EXPANSION_P (init))
init = tsubst_pack_expansion (init, args, complain, in_decl);
else
init = tsubst_copy_and_build (init, args, complain, in_decl,
/*fn*/false, /*constexpr*/false);
if (TREE_CODE (field) == TREE_VEC)
{
int len = TREE_VEC_LENGTH (field);
......
// PR c++/90732
// { dg-do compile { target c++14 } }
// { dg-additional-options "-Wno-vla" }
/*const*/ int SIZE = 100;
template<typename T>
int foo(T t) {
char buf[SIZE] = { 24 };
return [&buf](auto x){ return buf[x]; }(t);
}
int main() {
if (foo(0) != 24)
__builtin_abort();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment