aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-03-20 18:49:10 +0000
committerJason Merrill <jason@redhat.com>2017-03-20 18:49:10 +0000
commitd43cd87e50ed8188e32ff3445e40d86d64999495 (patch)
tree5c2706753e33aa0373e9e7fb94bbf729b43745af
parentdbba6db72277c45906ab5e9dc6e99d0d698c89ff (diff)
PR c++/79640 - infinite recursion with generic lambda.
* pt.c (tsubst_copy) [VAR_DECL]: Register the dummy instantiation before substituting its initializer. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@246289 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-const3.C15
3 files changed, 24 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a356fc77924..2797f8c7157 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2017-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/79640 - infinite recursion with generic lambda.
+ * pt.c (tsubst_copy) [VAR_DECL]: Register the dummy instantiation
+ before substituting its initializer.
+
2017-03-20 Marek Polacek <polacek@redhat.com>
Paolo Carlini <paolo.carlini@oracle.com>
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b8ce9fedf42..f1807106815 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14581,6 +14581,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
local static or constant. Building a new VAR_DECL
should be OK in all those cases. */
r = tsubst_decl (t, args, complain);
+ if (local_specializations)
+ /* Avoid infinite recursion (79640). */
+ register_local_specialization (r, t);
if (decl_maybe_constant_var_p (r))
{
/* We can't call cp_finish_decl, so handle the
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const3.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const3.C
new file mode 100644
index 00000000000..9c9dbac70ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const3.C
@@ -0,0 +1,15 @@
+// PR c++/79640
+// { dg-do compile { target c++14 } }
+
+template<typename F> void foo(F f)
+{
+ f(1);
+}
+
+template<int> void bar()
+{
+ const int i = i;
+ foo([] (auto) { sizeof(i); });
+}
+
+void baz() { bar<1>(); }