aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2019-02-08 14:50:03 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2019-02-08 14:50:03 +0000
commit4da5f970124d55511ab4db167ff9a14ed760a15e (patch)
tree442782f5a9eb3e19e2940d281d7f151a09c46758
parent2a97dfc988a695e44f759099f74e4a18c01fa9a5 (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/ChangeLog4
-rw-r--r--gcc/cp/lambda.c6
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-const6.C18
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);
+}