diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2019-02-08 14:50:03 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2019-02-08 14:50:03 +0000 |
commit | 4da5f970124d55511ab4db167ff9a14ed760a15e (patch) | |
tree | 442782f5a9eb3e19e2940d281d7f151a09c46758 | |
parent | 2a97dfc988a695e44f759099f74e4a18c01fa9a5 (diff) |
PR c++/88761 - ICE with reference capture of constant.
Here, we capture nf, then the use of the proxy decays to a constant during
semantic processing of +nf. Since we saw some decay from proxy to constant,
we walk through the lambda body to see which proxies are still used, but we
weren't walking into subtrees of DECL_EXPR at all, so we missed the use of
&nf in the initializer of y, and removed the capture. But then at
instantiation time we try to use nf, don't have a proxy anymore, and ICE.
* lambda.c (mark_const_cap_r): Do walk subtrees of DECL_EXPR for
non-proxy decls.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-8-branch@268702 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/lambda.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-generic-const6.C | 18 |
3 files changed, 26 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e0cff40cfa2..27f7032652f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-02-08 Jason Merrill <jason@redhat.com> + PR c++/88761 - ICE with reference capture of constant. + * lambda.c (mark_const_cap_r): Do walk subtrees of DECL_EXPR for + non-proxy decls. + PR c++/88752 - ICE with lambda and constexpr if. * cp-tree.h (LAMBDA_EXPR_INSTANTIATED): New. * pt.c (tsubst_lambda_expr): Set it. diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 9bdaa22d9fd..6c04393f1b1 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -1477,8 +1477,10 @@ mark_const_cap_r (tree *t, int *walk_subtrees, void *data) { tree decl = DECL_EXPR_DECL (*t); if (is_constant_capture_proxy (decl)) - var = DECL_CAPTURED_VARIABLE (decl); - *walk_subtrees = 0; + { + var = DECL_CAPTURED_VARIABLE (decl); + *walk_subtrees = 0; + } } else if (is_constant_capture_proxy (*t)) var = DECL_CAPTURED_VARIABLE (*t); diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const6.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const6.C new file mode 100644 index 00000000000..e85d6497488 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const6.C @@ -0,0 +1,18 @@ +// PR c++/88761 +// { dg-do compile { target c++14 } } + +template <class T> +void f(T t) { t(1); } + +int main() +{ + const unsigned long nf = 10'000'000; + + auto loop = [&](auto) + { + auto x = +nf; + auto y = &nf; + }; + + f(loop); +} |