diff options
author | Jason Merrill <jason@redhat.com> | 2018-02-01 21:07:09 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-02-01 21:07:09 -0500 |
commit | fe23b12a23e357103a40fda08df33f3547f112e6 (patch) | |
tree | 1eeccbcc99f8325a3a6b6c4e7886433ffdff17e1 /gcc/cp/lambda.c | |
parent | 60a57222fe2166519b54641766bccab92fa15606 (diff) | |
download | gcc-fe23b12a23e357103a40fda08df33f3547f112e6.zip gcc-fe23b12a23e357103a40fda08df33f3547f112e6.tar.gz gcc-fe23b12a23e357103a40fda08df33f3547f112e6.tar.bz2 |
PR c++/84160 - ICE with nested variadic capture.
* lambda.c (is_capture_proxy_with_ref): New.
(insert_capture_proxy): Don't set DECL_CAPTURED_VARIABLE from a
COMPONENT_REF.
* expr.c (mark_use): Use is_capture_proxy_with_ref.
* constexpr.c (potential_constant_expression_1): Likewise.
* semantics.c (process_outer_var_ref): Likewise.
From-SVN: r257325
Diffstat (limited to 'gcc/cp/lambda.c')
-rw-r--r-- | gcc/cp/lambda.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index e1caaef..ff8236a 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -290,13 +290,24 @@ is_normal_capture_proxy (tree decl) return DECL_NORMAL_CAPTURE_P (val); } +/* Returns true iff DECL is a capture proxy for which we can use + DECL_CAPTURED_VARIABLE. In effect, this is a normal proxy other than a + nested capture of a function parameter pack. */ + +bool +is_capture_proxy_with_ref (tree var) +{ + return (is_normal_capture_proxy (var) && DECL_LANG_SPECIFIC (var) + && DECL_CAPTURED_VARIABLE (var)); +} + /* VAR is a capture proxy created by build_capture_proxy; add it to the current function, which is the operator() for the appropriate lambda. */ void insert_capture_proxy (tree var) { - if (is_normal_capture_proxy (var)) + if (is_capture_proxy_with_ref (var)) { tree cap = DECL_CAPTURED_VARIABLE (var); if (CHECKING_P) @@ -443,11 +454,20 @@ build_capture_proxy (tree member, tree init) init = TREE_OPERAND (init, 0); STRIP_NOPS (init); } - gcc_assert (VAR_P (init) || TREE_CODE (init) == PARM_DECL); - while (is_normal_capture_proxy (init)) - init = DECL_CAPTURED_VARIABLE (init); - retrofit_lang_decl (var); - DECL_CAPTURED_VARIABLE (var) = init; + + if (TREE_CODE (init) == COMPONENT_REF) + /* We're capturing a capture of a function parameter pack, and have + lost track of the original variable. It's not important to have + DECL_CAPTURED_VARIABLE in this case, since a function parameter pack + isn't a constant variable, so don't bother trying to set it. */; + else + { + gcc_assert (VAR_P (init) || TREE_CODE (init) == PARM_DECL); + while (is_normal_capture_proxy (init)) + init = DECL_CAPTURED_VARIABLE (init); + retrofit_lang_decl (var); + DECL_CAPTURED_VARIABLE (var) = init; + } } if (name == this_identifier) |